Você está na página 1de 24

Funesdealtaordem ndice Criandoseusprpriostipose

typeclasses

Mdulos
Carregandomdulos
UmmduloHaskellumacoleodefunes,tiposetypeclasses.Umprograma
Haskellumacoleodemdulos,ondeomduloprincipalcarregaoutroseusa
suasfunesparafazeralgodetil.Terocdigodivididoemvriosmdulostem
vriasvantagens.Seomdulogenricoobastante,quandoexportadas,suas
funespodemserteisaumbandodesoftwares.Seoseuprpriocdigoest
separadoemmdulosquenorequeremunsaosoutros(muito),elespodemser
utilizveisemoutrosprojetos.umagrandevantagemperderalgumtempo
separandoseucdigoemalgumaspartescompropsitosadequados.

AbibliotecapadroHaskelldivididaemmdulos,quecontmtiposefunessemelhantesouquetmumuso
semelhante.Existeummduloparamanipulaodelistas,ummduloparaprogramaoconcorrente,ummdulopara
lidarcomnmeroscomplexos,etc.Todasasfunes,tiposetypeclassesquetrabalhamosatagorafazempartedo
mduloPrelude,quejimportadoautomaticamente.Nessecaptulo,daremosumaolhadaemalgunsmdulosteise
suasfunes.Masprimeiro,comoimportarmdulos.

AsintaxedeimportaomdulosemumscriptHaskellimport<nomedomdulo>.Issodeveserfeitoantesdedefinir
qualquerfuno,porissoimportaessofeitasgeralmentenoinciodoarquivo.Obviamenteumscriptpodeimportar
vriosmdulos,sprecisocolocarocdigoapropriadoemlinhasdistintas.EntovamosimportaromduloData.List
quepossuivriasfunesteisparasetrabalharcomlistas,inclusiveumaqueservirparanosdizerquantoselementos
nicosexistemnumadadalista.

importData.List

numUniques::(Eqa)=>[a]>Int
numUniques=length.nub

QuandovocdumimportData.List,todasasfunesdeimportData.Listtornamsedisponveisnonamespace
global,oquesignificaqueapartirdapodemosusarqualquerumadelasnomomentoquequisermos.nubumadas
funesdefinidasemData.Listquerecebeumalistaeretiratodososelementosrepetidos.Misturarlengthenub
fazendolength.nubresultaemumafunoequivalentea\xs>length(nubxs).

VoctambmpodecolocarfunesdemdulosnoglobalnamespacenoGHCI.SeestivernoGHCIequiserchamaruma
dasfunesdeData.List,vocpodefazer:

ghci>:m+Data.List
SeoquevocquercarregarvriosmdulosdentrodoGHCI,nonecessriodigitar:m+milharesdevezesporqueh
apossibilidadedefazeromesmoemapenasumalinha.

ghci>:m+Data.ListData.MapData.Set

Contudosejcarregouumscriptquecarregamdulos,nonecessriousar:m+novamente.

Seseuinteresseemapenasmeiadziadefunes,vocpodeimportarapenaselas.Paracarregarsomenteanubea
sortdoData.List,fazemosassim:

importData.List(nub,sort)

Vocaindapodeimportarcomexceestodasasfunesdeummdulo.Issotilquandomdulosexportamfunes
demesmonomeevocnoquersofrercomconflitos.Jquejfalamosdafunonub,vamosimportartodasasfunes
doData.Listmenosela:

importData.Listhiding(nub)

Outromeiodelidarcomconflitosdenomequalificarimportaes.OmduloData.Mapqueprovformasdepesquisar
valoresporchavesemestruturasdedados,exportavriasfunesdenomesrepetidoscomoPrelude,filterenull.
EntoquandoimportamosData.Mapechamamosfilter,Haskellnosabequalfunovocquer.Eassimque
resolvemosesseproblema:

importqualifiedData.Map

IssoquerdizerquequandoquisermosreferenciarafilterdoData.Map,temosquecolocarData.Map.filter,eque
filtercontinuasendonossofilterjconhecidoeamado.OproblemaquedigitarData.Mapnafrentedecadafuno
quepodedarproblemaumpoucotrabalhoso.Porissoquetambmpodemosrenomearimportaesqualificadaspara
algomaiscurto:

importqualifiedData.MapasM

AgoraparareferenciarafilterdoData.MapficaapenasM.filter.

Leiaessatimarefernciaparaverquaismdulosvmnabibliotecapadro.Umbommododeaprenderalgonovode
Haskellmergulharnabibliotecapadroparadescobrirmdulosefunescarregadasautomaticamente.Vocaindapode
lerseuscdigosfonte.EssetambmumdosmelhoresjeitosdeaprendereadquirirumconhecimentoslidoemHaskell.

Parapesquisarsobreeveralocalizaodefunes,useoHoogle.NesseincrvelsistemadebuscadeHaskell,voc
podepesquisarpornome,mduloouatmesmodeclaraesdetipo.

Data.List
OmduloData.Listobviamentelidacomlistas,provendofunesmuitoteisqueinclusivejconhecemosalgumas
(comomapefilter)porPreludejimportaralgoporconvenincia.VocnoprecisarimportarData.Listvia
importaoqualificadaporquenoconflitacomnadadoPrelude(excetoosjroubadosautomaticamente).Vamosdar
umaolhadaemalgumasqueaindanoconhecemos.

intersperse recebeumelementoeumalistaeorepeteentrecadaumdoselementosdalista.Vejas:

ghci>intersperse'.'"MONKEY"
"M.O.N.K.E.Y"
ghci>intersperse0[1,2,3,4,5,6]
[1,0,2,0,3,0,4,0,5,0,6]

intercalate pegaumalistadelistaseumalistasimpleseainsereentrecadauma,retornandoapenasumalistacomo
resultado.

ghci>intercalate""["hey","there","guys"]
"heythereguys"
ghci>intercalate[0,0,0][[1,2,3],[4,5,6],[7,8,9]]
[1,2,3,0,0,0,4,5,6,0,0,0,7,8,9]

transpose transpeumalistadelistas.Vendoumalistadelistascomoumamatriz,ascolunasviramlinhasevice
versa.

ghci>transpose[[1,2,3],[4,5,6],[7,8,9]]
[[1,4,7],[2,5,8],[3,6,9]]
ghci>transpose["hey","there","guys"]
["htg","ehu","yey","rs","e"]

Supondoquequeremossomarospolinmios3x 2+5x+9,10x 3+9e8x 3+5x 2+x1.Podemosrepresentlospormeio


daslistas[0,3,5,9],[10,0,0,9]e[8,5,1,1].Agoraparasomar,precisamosfazersoseguinte:

ghci>mapsum$transpose[[0,3,5,9],[10,0,0,9],[8,5,1,1]]
[18,8,6,17]

Quandotranspomosessastrslistas,aspotnciasde3estonaprimeiralinha,asde2nasegundaeassimpordiante.
Mapearsumdessesvaloresproduzoresultadoesperado.

foldl' e foldl1' soversesmaistrabalhadorasdoquesuasrespectivas


versespreguiosas.Aousarfoldspreguiosasemlistasgrandes,vocpodese
depararcomumestourodepilha.Oculpadodissoexatamenteanatureza
preguiosadasfunes,queaoinvsderealmenterealizaraoperaocomo
acumulado,somentedizquequandoforpedidoumresultado,eleirexecutarmais
essaoutraconta.Oproblemaquandotodoessebandodepromessasultrapassao
limitedamemria.Osfoldsseverosnosotopassveisdebugsporjrealizaras
operaesintermediriasaoinvsdeencherapilhadefalsaspromessas.Entose
voctiveressetipodeproblema,tenteusarsuasversestrabalhadoras.

concat concatenaumalistadelistasemapenasumalista.

ghci>concat["foo","bar","car"]
"foobarcar"
ghci>concat[[3,4,5],[2,3,4],[2,1,1]]
ghci>concat[[3,4,5],[2,3,4],[2,1,1]]
[3,4,5,2,3,4,2,1,1]

Somenteremoverumnveldecamadas.Entosevocquersimplificar[[[2,3],[3,4,5],[2]],[[2,3],[3,4]]]
umalistadelistas,precisaconcatenarduasvezes.

concatMap omesmoquemapearedepoisconcatenarumalista.

ghci>concatMap(replicate4)[1..3]
[1,1,1,1,2,2,2,2,3,3,3,3]

and recebeumalistadevaloresbooleanoseretornaTruesetodosforemTrue.

ghci>and$map(>4)[5,6,7,8]
True
ghci>and$map(==4)[4,4,4,3,4]
False

or relativamenteparecidocomoand,masretornaTruesenomnimoumdosvaloresforTrue.

ghci>or$map(==4)[2,3,4,5,6,1]
True
ghci>or$map(>4)[1,2,3]
False

any e all verificamseumpredicadoverdadeiroparanomnimoumoutodososelementosdalista(respectivamente).


Geralmenteusamosumadelasaoinvsdemapearedepoisusarandouor.

ghci>any(==4)[2,3,5,6,1,4]
True
ghci>all(>4)[6,9,10]
True
ghci>all(`elem`['A'..'Z'])"HEYGUYSwhatsup"
False
ghci>any(`elem`['A'..'Z'])"HEYGUYSwhatsup"
True

iterate tomaumafunoeumvalorinicial.Aplicaafunoaovalor,depoisaplicaafunoaoseuresultado,entoao
seuresultadonovamente...Retornaosresultadosnaformadeumalistainfinita.

ghci>take10$iterate(*2)1
[1,2,4,8,16,32,64,128,256,512]
ghci>take3$iterate(++"haha")"haha"
["haha","hahahaha","hahahahahaha"]

splitAt recebeumnmeroeumalista.Entoseparaalistaemelementos,retornandoumatupla.

ghci>splitAt3"heyman"
("hey","man")
ghci>splitAt100"heyman"
("heyman","")
ghci>splitAt(3)"heyman"

("","heyman")
("","heyman")
ghci>let(a,b)=splitAt3"foobar"inb++a
"barfoo"

takeWhile umafunosimples.Vaipegandooselementosdalistaenquantoaverificaoresultasatisfatoriamente.
Podeserbastantetil.

ghci>takeWhile(>3)[6,5,4,3,2,1,2,3,4,5,4,3,2,1]
[6,5,4]
ghci>takeWhile(/='')"Thisisasentence"
"This"

Digamosquequeirasaberasomadetodasaspotnciasmenoresde10000.Nopodemosmapear(^3),aplicarumfiltro
etentarsomarjquefiltrosemlistasinfinitasnuncaterminam.Vocpodesaberqueoselementossoascendentes,mas
Haskellno.Porissoquepodemosfazerisso:

ghci>sum$takeWhile(<10000)$map(^3)[1..]
53361

Aplicamos(^3)emumalistainfinitae,logoqueoelemento10000encontrado,alistacortada.Entosomamos
facilmente.

dropWhile semelhante,comadiferenadeledescartartodososelementoscomresultadoverdadeiro.QuandoFalse
encontrado,retornaorestodalista.Umafunofascinante.

ghci>dropWhile(/='')"Thisisasentence"
"isasentence"
ghci>dropWhile(<3)[1,2,2,2,3,4,5,4,3,2,1]
[3,4,5,4,3,2,1]

Nosentregaramumalistaquerepresentaosvaloresdeestoquepordatas.Alistafeitaportuplasondeoprimeiro
componenteoestoque,osegundooano,oterceiroomseoquartoodia.Queremossaberquandooestoque
excederos1000dlarespelaprimeiravez.

ghci>letstock=[(994.4,2008,9,1),(995.2,2008,9,2),(999.2,2008,9,3),(1001.4,2008,9,4),
(998.3,2008,9,5)]
ghci>head(dropWhile(\(val,y,m,d)>val<1000)stock)
(1001.4,2008,9,4)

span algocomootakeWhilemasqueretornaduaslistas.AprimeiralistacontmtudoqueotakeWhileretornaria
comomesmoteste.Asegundaalistaqueseriadescartada.

ghci>let(fw,rest)=span(/='')"Thisisasentence"in"Firstword:"++fw++",therest:"++rest
"Firstword:This,therest:isasentence"

Enquantoquespantomaoselementosenquantonoapareceroprimeirotruecomoresultadodoteste, break paraao


perceberqueafunoretornoutrue.Fazerbreakpoequivalenteaspan(not.p).

ghci>break(==4)[1,2,3,4,5,6,7]
ghci>break(==4)[1,2,3,4,5,6,7]
([1,2,3],[4,5,6,7])
ghci>span(/=4)[1,2,3,4,5,6,7]
([1,2,3],[4,5,6,7])

Aousarobreak,asegundalistateroprimeiroelementocomooquesatisfazoteste.

sort simplesmenteordenaumalista.OtipodoselementosdalistadeveserpartedatypeclassOrd,jquecomoseus
elementosnopodemsercolocadosemumaordem,obviamentenopodemserordenados.

ghci>sort[8,5,3,2,1,6,4,2]
[1,2,2,3,4,5,6,8]
ghci>sort"Thiswillbesortedsoon"
"Tbdeehiillnooorssstw"

group recebeumalistaeagrupaemnovaslistasoselementosiguais.

ghci>group[1,1,1,1,2,2,2,2,3,3,2,2,2,5,6,7]
[[1,1,1,1],[2,2,2,2],[3,3],[2,2,2],[5],[6],[7]]

Seordenarmosedepoisagruparmosumalista,podemosdescobrirquantasvezescadaelementoaparece.

ghci>map(\l@(x:xs)>(x,lengthl)).group.sort$[1,1,1,1,2,2,2,2,3,3,2,2,2,5,6,7]
[(1,4),(2,7),(3,2),(5,1),(6,1),(7,1)]

inits e tails sosemelhantesainitetail,comadiferenaqueasprimeirasvoaplicandorecursivamenteo


mtodoatofimdalista.Confira:

ghci>inits"w00t"
["","w","w0","w00","w00t"]
ghci>tails"w00t"
["w00t","00t","0t","t",""]
ghci>letw="w00t"inzip(initsw)(tailsw)
[("","w00t"),("w","00t"),("w0","0t"),("w00","t"),("w00t","")]

Vamosusarfoldparaimplementarumapesquisaporsublistasemlistas.

search::(Eqa)=>[a]>[a]>Bool
searchneedlehaystack=
letnlen=lengthneedle
infoldl(\accx>iftakenlenx==needlethenTrueelseacc)False(tailshaystack)

Primeirochamamostailscomalistaqueprocuramos.Entocomparasecada"cauda"comalista.

Comisso,criamosalgocomofuncionamentodafuno isInfixOf . isInfixOf procuraporumasublistaemumalista


eretornaTrueseforencontradaemalgumlugar.

ghci>"cat"`isInfixOf`"imacatburglar"
True
ghci>"Cat"`isInfixOf`"imacatburglar"
False

ghci>"cats"`isInfixOf`"imacatburglar"
ghci>"cats"`isInfixOf`"imacatburglar"
False

isPrefixOf e isSuffixOf procuramporsublistasnofimeinciodeumalista.

ghci>"hey"`isPrefixOf`"heythere!"
True
ghci>"hey"`isPrefixOf`"ohheythere!"
False
ghci>"there!"`isSuffixOf`"ohheythere!"
True
ghci>"there!"`isSuffixOf`"ohheythere"
False

elem e notElem verificamseumelementoestounodentrodeumalista.

partition recebeumalistaeumpredicadoeretornaumpardelistas.Aprimeiralistaresultantecontmtodosos
elementosquesatisfazemopredicado,asegundaqueno.

ghci>partition(`elem`['A'..'Z'])"BOBsidneyMORGANeddy"
("BOBMORGAN","sidneyeddy")
ghci>partition(>3)[1,3,5,6,3,2,1,0,3,7]
([5,6,7],[1,3,3,2,1,0,3])

importantesaberdiferenciardespanebreak:

ghci>span(`elem`['A'..'Z'])"BOBsidneyMORGANeddy"
("BOB","sidneyMORGANeddy")

Enquantospanebreakterminamaoencontraroprimeiroelementoquenosatisfazopredicado,partitionpassapor
todaalistaeseparaaoencontraropredicado.

find recebeumalistaeumpredicadoeretornaoprimeiroelementoquesatisfazopredicado(dentrodeumvalorMaybe).
Nsiremosvertiposdedadosalgbricosmelhornoprximocaptulo,masporenquanto:umvalorMaybe(possivelmente)
podeserJustsomething(apenasalgumacoisa)ouNothing(nada).Domesmojeitoqueumalistapodeternenhumou
vrioselementos,umvalorMaybepodeternadaouumvalor.Domesmojeitoqueumalistadenmerosinteiro[Int],o
tipoquepossivelmentetemuminteiroMaybeInt.Bom,testemosofind.

ghci>find(>4)[1,2,3,4,5,6]
Just5
ghci>find(>9)[1,2,3,4,5,6]
Nothing
ghci>:tfind
find::(a>Bool)>[a]>Maybea

Vejaotipodefind.Maybea.Issomuitoparecidocomser[a],masoMaybepodeconterumouzeroelementos,
enquantoumalistapodeconterum,zeroouvrioselementos.

Lembrasedequandoprocuramosaprimeiravezqueoestoqueultrapassou$1000.Fizemos
head(dropWhile(\(val,y,m,d)>val<1000)stock).Lembresequeheadnomuitoseguro.Oque
acontecesenossoestoquenuncachegoua$1000?NossousodadropWhileretornariaumalistavaziaeaopegarmoso
primeiroelementodenadaseriageradoumerro.Noentanto,sereescrevssemospara
find(\(val,y,m,d)>val>1000)stock,seriamuitomaisseguro.Seoestoquenuncachegoua$1000(que
nenhumelementosatisfezopredicado),seriaretornadoNothing.Masumarespostavlidadessalistaseria,digamos,
Just(1001.4,2008,9,4).

elemIndex semelhanteaoelem,masquenoretornaumvalorbooleano.Provavelmenteretornaraposiodo
elemento.Casooelementonoexistanalista,Nothing.

ghci>:telemIndex
elemIndex::(Eqa)=>a>[a]>MaybeInt
ghci>4`elemIndex`[1,2,3,4,5,6]
Just3
ghci>10`elemIndex`[1,2,3,4,5,6]
Nothing

elemIndices semelhanteaoelemIndex,masretornaumalistadeposies,nocasodonossoelementoaparecer
vriasvezes.Comoestamosusandoumalistapararepresentarosndices,noprecisamosdeumtipoMaybe,jqueo
erropodeserrepresentadoporumalistavazia,muitosemelhanteaoNothing.

ghci>''`elemIndices`"Wherearethespaces?"
[5,9,13]

findIndex parecidocomofind,masretornaapenasaposiodoprimeiroelementoquesatisfazopredicado.
findIndices retornaosndicesdetodososelementosquesatisfazopredicadonaformadeumalista.

ghci>findIndex(==4)[5,3,2,1,6,4]
Just5
ghci>findIndex(==7)[5,3,2,1,6,4]
Nothing
ghci>findIndices(`elem`['A'..'Z'])"WhereAreTheCaps?"
[0,6,10,14]

JvimoszipezipWith.Elascombinam("transpem")duaslistasemtuplasouporumafunobinria(oquesignifica
precisardedoisparmetros).Masesequisermoscombinartrslistas?Oucombinartrslistascomumafunodetrs
parmetros?Paraissotemosas zip3 , zip4 ,etc.e zipWith3 , zipWith4 ,etc.Variaesquevoat7.Pode
parecerumagambiarra,masfuncionamuitobem,almdenosersemprequeprecisotranspor8listas.Aindaexisteum
modomuitoprticodecombinarlistasinfinitas,masnoavanamososuficienteparaveressaparte.

ghci>zipWith3(\xyz>x+y+z)[1,2,3][4,5,2,2][2,2,3]
[7,9,8]
ghci>zip4[2,3,3][2,2,2][5,5,3][2,2,2]
[(2,2,5,2),(3,2,5,2),(3,2,3,2)]

Igualmentetransposiocomum,listasmaioresqueamenorsocortadasnessaquantidadedeelementos.

lines umafunomuitotilaolidarcomarquivosouqualqueroutrotipodeentrada.Recebeumastringeretornacada
linhadastringcomoumalista.

ghci>lines"firstline\nsecondline\nthirdline"
["firstline","secondline","thirdline"]
'\n'ocaractereparaumanovalinhaUnix.Barrasinvertidassempretmumsignificadoespecialemstringse
caracteresemHaskell.

unlines oinversodafunolines.Recebeumalistadestringseasunepelocaractere'\n'.

ghci>unlines["firstline","secondline","thirdline"]
"firstline\nsecondline\nthirdline\n"

words e unwords soparasepararumalinhadetextoempalavrasouunirnaordemcontrria.Muitotil.

ghci>words"heythesearethewordsinthissentence"
["hey","these","are","the","words","in","this","sentence"]
ghci>words"heythesearethewordsinthis\nsentence"
["hey","these","are","the","words","in","this","sentence"]
ghci>unwords["hey","there","mate"]
"heytheremate"

Jmencionamosafuno nub .Recebeumalistaeretiraoselementosduplicados,retornandoumalistaquetemosa


certezadoselementosnopossuremnenhumgmeoperdido.Masessafunotemumnomebemcurioso.Aexpresso
"nub"significaaparteessencialouprioritriadealgo.Naminhaopinio,nomesdefunesdeveriamternomesmais
parecidoscomoseurealsignificadoaoinvsdeseprenderaantigasdefinies.

ghci>nub[1,2,3,4,3,2,1,2,3,4,3,2,1]
[1,2,3,4]
ghci>nub"Lotsofwordsandstuff"
"Lotsfwrdanu"

delete recebeumelementoeumalistaeremovesuaprimeiraocorrncia.

ghci>delete'h'"heythereghang!"
"eythereghang!"
ghci>delete'h'.delete'h'$"heythereghang!"
"eytereghang!"
ghci>delete'h'.delete'h'.delete'h'$"heythereghang!"
"eyteregang!"

\\ umafunodediferenadelistas.Resumindo,trazadiferena.Paracadaelementodalista2,removeseo
correspondente(seexistente)na1.

ghci>[1..10]\\[2,5,9]
[1,3,4,6,7,8,10]
ghci>"Imabigbaby"\\"big"
"Imababy"

Fazer[1..10]\\[2,5,9]omesmoquedelete2.delete5.delete9$[1..10].

union tambmfazumaoperaodeconjuntos.Retornaauniodeduaslistas.Funcionacolocandocadaelementoda
lista2na1,senoexistente.

ghci>"heyman"`union`"manwhat'sup"
ghci>"heyman"`union`"manwhat'sup"
"heymanwt'sup"
ghci>[1..7]`union`[5..10]
[1,2,3,4,5,6,7,8,9,10]

intersect significainterseco.Retornaapenasoselementosencontradosemambaslistas.

ghci>[1..7]`intersect`[5..10]
[5,6,7]

insert recebeumelementoeumalistadeelementosquepodemserordenados.Ento,oinserelogodepoisqueo
menorouigualmaisprximo.Seusarmosinsertemumalistaordenada,oresultadopermanecerordenado.

ghci>insert4[1,2,3,5,6,7]
[1,2,3,4,5,6,7]
ghci>insert'g'$['a'..'f']++['h'..'z']
"abcdefghijklmnopqrstuvwxyz"
ghci>insert3[1,2,4,3,2,1]
[1,2,3,4,3,2,1]

length,take,drop,splitAt,!!ereplicatetmemcomumreceberemumIntcomoparmetro,mesmosabendoque
ocdigoficariamaisgenricoaceitandotodostiposdeIntegralouNum(dependendodecadafuno).Issofeitopor
razesdecompatibilidade.Mudarissocomcertezaquebrariamuitocdigoantigo.PorissoqueData.Listimplementou
versessuasmaisgenricas: genericLength , genericTake , genericDrop , genericSplitAt , genericIndex
e genericReplicate .lengthtemtipolength::[a]>Int.Sevoctentardescobriramdiadenmeroscom
letxs=[1..6]insumxs/lengthxsterumerro,jquevocnopodeusar/comInt.genericLengthpor
outrolado,temtipogenericLength::(Numa)=>[b]>a.ComoNumpodeagircomopontoflutuante,vocpode
conseguiroresultadoesperadocomletxs=[1..6]insumxs/genericLengthxs.

nub,delete,union,intersectegrouptmtambmversesgenricascomnomes nubBy , deleteBy , unionBy ,


intersectBy e groupBy .Adiferenaqueasprimeirasversesusam==paratestarporigualdade,enquantosuas
versesByrequeremtambmumafunoparacomparao.groupomesmoquegroupBy(==).

Porhora,digamosquetemosumalistaquedescreveosvaloresdeumasegundaensqueremosdividiremsublistas
baseadoseoelementoestabaixoouacimadezero.Seusssemosogroupcomum,apenasagrupariavalores
adjacentes.Masqueremosclassificarquantoposiodezero.aquegroupBymostrasuautilidade!Afunode
igualdadedasfunesByprecisareceberdoiselementosdemesmotipoeretornarTrue,independentedosseuscritrios
paraisso.

ghci>letvalues=[4.3,2.4,1.2,0.4,2.3,5.9,10.5,29.1,5.3,2.4,14.5,2.9,2.3]
ghci>groupBy(\xy>(x>0)==(y>0))values
[[4.3,2.4,1.2],[0.4,2.3,5.9,10.5,29.1,5.3],[2.4,14.5],[2.9,2.3]]

Logoidentificamoscomofazernossoteste.AfunodeigualdaderetornarTruesomenteseambosforemnegativosou
positivos.Essafunodeigualdadepodeserescritapor\xy>(x>0)&&(y>0)||(x<=0)&&(y<=0),
apesardeacharquedoprimeirojeitoficoumuitomaislegvel.UmmodomuitomelhordeescreverfunesBy
importandoafuno on deData.Function.ondefinidaassim:

on::(b>b>c)>(a>b)>a>a>c
f`on`g=\xy>f(gx)(gy)
f`on`g=\xy>f(gx)(gy)

Fazendo(==)`on`(>0)retornaumafunodeigualdadesemelhantea\xy>(x>0)==(y>0).onmuito
usadaporfunesBy,jquepossvelfazerisso:

ghci>groupBy((==)`on`(>0))values
[[4.3,2.4,1.2],[0.4,2.3,5.9,10.5,29.1,5.3],[2.4,14.5],[2.9,2.3]]

Muitomaislegvel!Agoravocpodeleremvozalta:Agrupeporigualdadesemprequeelementosforemmaioresdoque
zero.

Semelhantemente,sort,insert,maximumeminimumtambmtmversesgenricas.FunescomogroupByrecebem
umafunoparadeterminarquandodoiselementossoiguais. sortBy , insertBy , maximumBy e minimumBy
recebemumafunoquedizseumelementomaior,menorouigualaoutro.OtipodesortBye
sortBy::(a>a>Ordering)>[a]>[a].Sevocaindaselembra,otipoOrderingpodeassumirvalorLT,
EQouGT.sortoequivalenteasortBycompare,porquecomparepegadoistiposdeOrderetornasuarelaoquanto
ordenao.

Listaspodemsercomparadas,masquandooso,socomparadoslexicograficamente.Esequisermosordenarumalista
delistasnobaseadonaslistasinternas,masemseustamanhos?Comodeveterimaginado,sortByanossasoluo.

ghci>letxs=[[5,4,5,4,4],[1,2,3],[3,5,4,3],[],[2],[2,2]]
ghci>sortBy(compare`on`length)xs
[[],[2],[2,2],[1,2,3],[3,5,4,3],[5,4,5,4,4]]

Incrvel!compare`on`length...cara,issomaispareceinglspuro!Sevocnopercebeubemcomoonfuncionaaqui,
compare`on`lengthoequivalentea\xy>lengthx`compare`lengthy.Quandovocesttrabalhando
comfunesByqueprecisamdeumafunodeigualdade,vocgeralmentevaiusar(==)`on`somethingecom
funesByqueprecisemdeoutradeordenao,vocusacompare`on`something.

Data.Char
OmduloData.Charexatamenteoqueoseunomesugere.Exportafunesque
lidamcomcaracteres.extremamentetilparafiltraroumapearstrings,quenada
maissodoquelistasdecaracteres.

Data.Chartambmexportavriospredicadosdecaracteres.Isto,funesque
recebemumcaracterenosdizseumaproposioverdadeiraoufalsa.Alguns
exemplos:

isControl testaseumcaracterumcaracterdecontrole.

isSpace testaseumcaracterumespaoembranco,oqueincluiespaos,tabs,
novaslinhas,etc.

isLower testaseumcaracterminsculo.
isUpper testaseumcaractermaisculo.

isAlpha testaseumcaracterumaletra.

isAlphaNum testaseumcaracterumaletraouumnmero.

isPrint testaseumcaracterimprimvel.Caracteresdecontrole,porexemplo,noso.

isDigit testaseumcaracterumdgito.

isOctDigit testaseumcaracterumdgitooctal.

isHexDigit testaseumcaracterumdgitohexadecimal.

isLetter testaseumcaracterumaletra.

isMark testaseumcaracterumcaracterdemarcaoUnicode,quequandocombinadoscomletrasprecedentes,
formamletrascomacentos.Useseforfrancs.

isNumber testaseumcaracternumrico.

isPunctuation testaseumcaracterumapontuao.

isSymbol testaseocaractersimbolo,inclusivesimbolosmatemticosoudemoedas.

isSeparator testaseumcaracterespaoouseparadorUnicode.

isAscii testaseumcaracterumdosprimeiros128Unicode.

isLatin1 testaseumcaracterumdosprimeiros256Unicode.

isAsciiUpper testaseumcaracterASCIIemaisculo.

isAsciiLower testaseumcaracterASCIIeminsculo.

TodosessespredicadostmtiposChar>Bool.Namaiorpartedasvezeselesserousadosparafiltraralgodestrings.
Porexemplo,digamosqueestamosfazendoumprogramacomloginquenecessitaqueousuriosejacompostoapenas
porcaracteresalfanumricos.PoderamosusarafunoalldoData.Listemcombinocompredicadosdo
Data.Charparatestarsuavalidade.

ghci>allisAlphaNum"bobby283"
True
ghci>allisAlphaNum"eddythefish!"
False

Quebacana!Casonoselembre,allrecebeumpredicadoeumalistaeretornaTrueapenasseopredicadoaprova
todososelementos.
PodemosaindausaraisSpaceparasimularofuncionamentodafunowordsdoData.List.

ghci>words"heyguysitsme"
["hey","guys","its","me"]
ghci>groupBy((==)`on`isSpace)"heyguysitsme"
["hey","","guys","","its","","me"]
ghci>

Hmmm,muitoparecidomesmo,masmanteveosespaosembranco.Oquepoderamosfazer?Eusei,pelomenos.
Vamosfiltraressepessoal.

ghci>filter(not.anyisSpace).groupBy((==)`on`isSpace)$"heyguysitsme"
["hey","guys","its","me"]

Ah.

AData.CharaindaexportaotipodedadosOrdering.OOrderingpodetervalorLT,EQouGT.comouma
enumerao.Descreveospossveisresultadosaocomparardoiselementos.OtipoGeneralCategorytambmuma
enumerao.Temalgumaspossveiscategoriasqueumcaracterpodeseencaixar.Aprincipalfunodeconseguira
categoriageraldecaracteresgeneralCategory.TemtipogeneralCategory::Char>GeneralCategory.
Existemaindaoutras31categoriasquenolistaremosaqui,masvamosdarumaolhadanafuno.

ghci>generalCategory''
Space
ghci>generalCategory'A'
UppercaseLetter
ghci>generalCategory'a'
LowercaseLetter
ghci>generalCategory'.'
OtherPunctuation
ghci>generalCategory'9'
DecimalNumber
ghci>mapgeneralCategory"\t\nA9?|"
[Space,Control,Control,UppercaseLetter,DecimalNumber,OtherPunctuation,MathSymbol]

JqueotipoGeneralCategorypartedatypeclassEq,poderamostestaralgocomogeneralCategoryc==Space.

toUpper converteumcaracterparamaisculo.Espaos,nmeroseoutrospermanecemiguais.

toLower converteumcaracterparaminsculo.

toTitle converteumcaracterparatitlecase.Paraamaioriadoscaracteres,titlecaseomesmoquemaisculas.

digitToInt converteumcaracterparaInt.Paraquefuncione,ocaracterdeveestarnasranges'0'..'9','a'..'f'
ou'A'..'F'.

ghci>mapdigitToInt"34538"
[3,4,5,3,8]
ghci>mapdigitToInt"FF85AB"
[15,15,8,5,10,11]
intToDigit oinversodafunodigitToInt.RecebeumIntnarange0..15econverteparaumcaracter
minsculo.

ghci>intToDigit15
'f'
ghci>intToDigit5
'5'

Asfunes ord echrconvertemcaracteresparaseuscorrespondentesemnmeroseviceversa:

ghci>ord'a'
97
ghci>chr97
'a'
ghci>mapord"abcdefgh"
[97,98,99,100,101,102,103,104]

OsvaloresorddedoiscaracteresreferentetabelaUnicode.OCdigodeCsarummtodoprimitivodecodificar
mensagensaoassociarcaracteresporumcorrespondente(seguindoamesmasequncia).Nsmesmospoderamos
construirnossocdigocriptografadosemprecisardebruarsobreumalfabeto.

encode::Int>String>String
encodeshiftmsg=
letords=mapordmsg
shifted=map(+shift)ords
inmapchrshifted

Aqui,primeiroconvertemosnossastringparaumalistadenmeros.Entoaumentamosoudiminuimosumacerta
quantidadedeinteirosdetodaalistaeconvertemosdevoltaparacaracteres.Sevocjestcraquenacriaode
funes,jescreveumap(chr.(+shift).ord)msg.Vamostentarcriptografaralgumasmensagens.

ghci>encode3"Heeeeey"
"Khhhhh|"
ghci>encode4"Heeeeey"
"Liiiii}"
ghci>encode1"abcd"
"bcde"
ghci>encode5"MarryChristmas!Hohoho!"
"Rfww~%Hmwnxyrfx&%Mt%mt%mt&"

Parecequeestcerto.Paradecodificaramensagemsnecessriovoltaronmerodeposiesemtodoscaracteres,
trazendoosposioinicial.

decode::Int>String>String
decodeshiftmsg=encode(negateshift)msg

ghci>encode3"Imalittleteapot"
"Lp#d#olwwoh#whdsrw"
ghci>decode3"Lp#d#olwwoh#whdsrw"
"Imalittleteapot"
ghci>decode5.encode5$"Thisisasentence"
"Thisisasentence"

Data.Map
Data.Map
Listasdeassociao(tambmchamadasdedicionrios)solistasusadasparaarmazenarparesdechaveevalor,onde
suaordemnoconsiderada.Porexemplo,podemosusarumalistadeassociaoparaguardarnmerosdetelefone
(queseriamosvalores)juntodonomedosdonos(chaves).Aordemqueessesdadosestoarmazenadosnoimporta
parans,desdequeconsigamosonmerocertoaopesquisarporumapessoa.

OmodomaisbviodearmazenarlistasdeassociaoemHaskellseriaumalistadepares.Ondeoprimeirocomponente
dopardeveserachave,eosegundocomponenteovalor.Aquivaiumexemplodeumalistadeassociaocomnmeros
detelefone:

phoneBook=
[("mari","5552938")
,("carol","4522928")
,("patrcia","4932928")
,("luciana","2052928")
,("aline","9398282")
,("camila","8532492")
]

Tirandoaidentaobizarra,issoapenasumalistadeparesdestrings.Oobjetivomaiscomumaolidarcomlistasde
associaoabuscaporchave.Vamoscriarumafunoqueprocuraporumadadachave.

findKey::(Eqk)=>k>[(k,v)]>v
findKeykeyxs=snd.head.filter(\(k,v)>key==k)$xs

Extremamentesimples.Afunorecebeumachaveeumalista,filtraalistaparaquepermaneamapenasosquetm
chavecorrespondenteeretornaoprimeiroparchavevalor.Masoqueaconteceaoprocurarmosporumachave
inexistente?Bem,nstentaramospegaroprimeiroelementodeumalistavazia,gerandoumruntimeerror.Mas
precisamosfazerosnossosprogramasparaquesejamumpoucomaisdifceisdequebrar,entousaremosotipoMaybe.
Senoencontrarumachave,retornarNothing.Seencontrar,retornarJustalgumacoisa,onde"algumacoisa"o
valorcorrespondentechave.

findKey::(Eqk)=>k>[(k,v)]>Maybev
findKeykey[]=Nothing
findKeykey((k,v):xs)=ifkey==k
thenJustv
elsefindKeykeyxs

Presteatenodeclaraodetipo.Elarecebeumachavequepodeserigualada,umalistadeassociaoetalvez
devolvaumvalor.Parececorreto.

Essaumafunodeagendadecontatosquetrabalhacomumalista.Temosacondiolimite,quebramosalistaemuma
cabeaeumacauda,temoschamadasrecursivas,estatudoali.Esseocasoclssicodeusodopadrodefolding.
Vamostentarimplementarentocomfolds.

findKey::(Eqk)=>k>[(k,v)]>Maybev
findKeykey=foldr(\(k,v)acc>ifkey==kthenJustvelseacc)Nothing
Dica:Geralmentemelhorusarfoldsparalistasdepadresrecursivosaoinvsdeescreverexplicitamentearecurso
porquemaisfcildeseler.Todossabemoqueumfoldaoverachamadafunofoldr,mastomamaistempo
paraentendertodoseuprocessoderecurso.

ghci>findKey"camila"phoneBook
Just"8532492"
ghci>findKey"mari"phoneBook
Just"5552938"
ghci>findKey"wilma"phoneBook
Nothing

Funcionaqueumabeleza!Agorasfaltavocusarsuanovaagendaparaverse
noficasnapesquisa.

NsacabamosdeimplementarafunolookupdoData.List.Sequisermosachar
umvalorcorrespondenteaumachave,precisamospercorrertodososelementosat
encontrlo.OmduloData.Mapoferecelistasdeassociaomuitomaisrpidas
(porqueelassoimplementadasinternamentecomrvores)eaindaprovalgumas
funesteis.Deagoraemdianteusaremosmapasaoinvsdelistasdeassociao.

JqueData.MapexportafunesqueconflitamcomoutrasdePreludeeData.List,
faremosumaimportaoqualificada.

importqualifiedData.MapasMap

ColoqueessecomandoparaimportaonoscriptecarregueoviaGHCI.

ChegadeenrolarevamosveroqueoData.Mapnosguarda!Avaiumresumorpidodesuasfunes.

Afuno fromList recebeumalistadeassociaes(naformadeumalistamesmo)eretornaummapacomamesma


estrutura.

ghci>Map.fromList[("mari","5552938"),("carol","4522928"),("luciana","2052928")]
fromList[("mari","5552938"),("carol","4522928"),("luciana","2052928")]
ghci>Map.fromList[(1,2),(3,4),(3,2),(5,5)]
fromList[(1,2),(3,2),(5,5)]

Seexistiremchavesduplicadasnalistadeassociaooriginal,asduplicadassodescartadas.Essaaassinaturade
tipodefromList.

Map.fromList::(Ordk)=>[(k,v)]>Map.Mapkv

EladizquefromListrecebeumalistadeparesdetiposkeveretornaummapacomchavesdetipoketipov.Perceba
quequandovocestcriandolistasdeassociaocomlistas,aschavessprecisamserpossveisdeseremigualadas
(teremtipospertencentestypeclassEq)masnonecessariamenteordenveis.EssaaessnciadomduloData.Map.
Eleprecisaqueaschavessejamordenveisparaorganizlasnaformadeumarvore.
sempreaconselhvelusaroData.Mapparaassociaeschavevalor,amenosqueotiponoestejanatypeclassOrd.

empty representaummapavazio.Nonecessitadenenhumargumento,sretornaummapavazio.

ghci>Map.empty
fromList[]

insert recebeumachave,umvaloreummapaeretornaumnovomapaigualaoantigo,mascomchavesevalor
adicionados.

ghci>Map.empty
fromList[]
ghci>Map.insert3100Map.empty
fromList[(3,100)]
ghci>Map.insert5600(Map.insert4200(Map.insert3100Map.empty))
fromList[(3,100),(4,200),(5,600)]
ghci>Map.insert5600.Map.insert4200.Map.insert3100$Map.empty
fromList[(3,100),(4,200),(5,600)]

NspodemosimplementarnossoprpriofromListusandoummapavazio,inserteumfold.Vejas:

fromList'::(Ordk)=>[(k,v)]>Map.Mapkv
fromList'=foldr(\(k,v)acc>Map.insertkvacc)Map.empty

Umfoldbastantesimples.Comeamoscomummapavazioedobramosdireita,inserindoosparesdechavevalorno
acumuladoremcadapasso.

null testaseummapaestvazio.

ghci>Map.nullMap.empty
True
ghci>Map.null$Map.fromList[(2,3),(5,5)]
False

size reportaotamanhodeummapa.

ghci>Map.sizeMap.empty
0
ghci>Map.size$Map.fromList[(2,4),(3,3),(4,2),(5,4),(6,4)]
5

singleton recebeumachaveeumvalorecriaummapacomapenasessesdados.

ghci>Map.singleton39
fromList[(3,9)]
ghci>Map.insert59$Map.singleton39
fromList[(3,9),(5,9)]

lookup funcionacomooData.Listlookup,masoperaapenasemmapas.RetornaJustsomethingseencontraralgo
pelachaveprocurada,Nothingseencontrarnada.
member umpredicadoquerecebeumachaveeummapaedizseachaveexisteounonomapa.

ghci>Map.member3$Map.fromList[(3,6),(4,3),(6,9)]
True
ghci>Map.member3$Map.fromList[(2,5),(4,5)]
False

map e filter funcionamsemelhantementeaoshomnimosdaslistas.

ghci>Map.map(*100)$Map.fromList[(1,1),(2,4),(3,9)]
fromList[(1,100),(2,400),(3,900)]
ghci>Map.filterisUpper$Map.fromList[(1,'a'),(2,'A'),(3,'b'),(4,'B')]
fromList[(2,'A'),(4,'B')]

toList oinversodafromList.

ghci>Map.toList.Map.insert92$Map.singleton43
[(4,3),(9,2)]

keys e elems retornamlistasdechavesevalores,respectivamente.keysoequivalenteamapfst.Map.toListe


elemsodemapsnd.Map.toList.

fromListWith umafunomuitolegal.AgecomofromList,masaoinvsdediscartaraschavesduplicadas,recebe
tambmumafunoquedecideoquefazercomelas.Imaginequeumagarotapodetervriosnmerosetemosumalista
deassociaocomoessa:

phoneBook=
[("mari","5552938")
,("mari","3422492")
,("carol","4522928")
,("patrcia","4932928")
,("patrcia","9432929")
,("patrcia","8279162")
,("luciana","2052928")
,("aline","9398282")
,("camila","8532492")
,("camila","5552111")
]

AgorasequisermosusarfromListparacriarummapa,perderemosalgunsnmeros!Entoassimquevamosfazer:

phoneBookToMap::(Ordk)=>[(k,String)]>Map.MapkString
phoneBookToMapxs=Map.fromListWith(\number1number2>number1++","++number2)xs

ghci>Map.lookup"patrcia"$phoneBookToMapphoneBook
"8279162,9432929,4932928"
ghci>Map.lookup"aline"$phoneBookToMapphoneBook
"9398282"
ghci>Map.lookup"mari"$phoneBookToMapphoneBook
"3422492,5552938"
Seumachaveduplicadaforencontrada,afunoquepassamosserusadaparacombinarosvaloresdaschavesem
outrovalor.Poderamosprimeiroterlistasnicasparaosvaloreseusarmos++parafazeracombinao.

phoneBookToMap::(Ordk)=>[(k,a)]>Map.Mapk[a]
phoneBookToMapxs=Map.fromListWith(++)$map(\(k,v)>(k,[v]))xs

ghci>Map.lookup"patrcia"$phoneBookToMapphoneBook
["8279162","9432929","4932928"]

Muitoelegante!Outrocasodeusoquandocriamosummapacombaseemumalistadeassociaodenmerose
quandoencontramosumachaveduplicada,queremosomaiorvalordachaveparamantelo.

ghci>Map.fromListWithmax[(2,3),(2,5),(2,100),(3,29),(3,22),(3,11),(4,22),(4,15)]
fromList[(2,100),(3,29),(4,22)]

Oupodemosoptarporadicionarvaloresjuntoamesmachave.

ghci>Map.fromListWith(+)[(2,3),(2,5),(2,100),(3,29),(3,22),(3,11),(4,22),(4,15)]
fromList[(2,108),(3,62),(4,37)]

insertWith parainsertoquefromListWithparafromList.Eleinsereumparchavevaloremummapa,porm
seomapajtiverachave,eleusaafunopassadaparadeterminaroquefazer.

ghci>Map.insertWith(+)3100$Map.fromList[(3,4),(5,103),(6,339)]
fromList[(3,104),(5,103),(6,339)]

EstassoapenasalgumasfunesdoData.Map.Vocpodeaindaverumalistacompletadefunesnadocumentao.

Data.Set
OmduloData.Setnosoferececonjuntos.Conjuntosmatemticos,issomesmo.Conjuntos
soalgoentrelistasemapas.Todososelementosemumconjuntosonicos.Eporserem
internamenteimplementadosporrvores(semelhantementeamapasdoData.Map),so
ordenados.Checarexistncia,insero,deleo,etc.muitomaisrpidodoquecomlistas.As
operaesmaiscomunsfalandosedeconjuntosinserir,checarexistnciaeconverterpara
lista.

PelosnomesdoData.SetfrequentementeconflitaremcommembrosdePreludeeData.List,
fazemosumaimportaoqualificada.

Coloqueessalinhanoseuscript:

importqualifiedData.SetasSet

EentocarregueoviaGHCI.
Temosdoispedaosdeumtexto.Queremosdescobrirquaiscaracteressousadosemambos.

text1="Eutiveumsonhocomanimes.Anime...Realidade...Temalgumadiferenca?"
text2="Ovelhotedeixoualixeiradelelaforaeagoraolixodeleestatodoespalhadonomeugramado!"

Afuno fromList fazexatamenteoquevocimagina.Recebeumalistaeconverteaemumconjunto.

ghci>letset1=Set.fromListtext1
ghci>letset2=Set.fromListtext2
ghci>set1
fromList".?AERTacdefghilmnorstuv"
ghci>set2
fromList"!Oadefghilmnoprstuvx"

Comopodever,ositenssoordenadosecadaelementosonicos.Usaremos intersection paradescobrirquais


estoemambos.

ghci>Set.intersectionset1set2
fromList"adefghilmnorstuv"

Podemosaindausar difference paraverquaisletrasestonoprimeiromasnonosegundoconjuntoeviceversa.

ghci>Set.differenceset1set2
fromList".?AERTc"
ghci>Set.differenceset2set1
fromList"!Opx"

Outambmpodemosgerarumterceiroconjuntocomasletrasqueaparecememqualquerumdosdoisprimeirosusando
union .

ghci>Set.unionset1set2
fromList"!.?AEORTacdefghilmnoprstuvx"

Asfunes null , size , member , empty , singleton , insert e delete vocjdeveimaginarparaqueservem.

ghci>Set.nullSet.empty
True
ghci>Set.null$Set.fromList[3,4,5,5,4,3]
False
ghci>Set.size$Set.fromList[3,4,5,3,4,5]
3
ghci>Set.singleton9
fromList[9]
ghci>Set.insert4$Set.fromList[9,3,8,1]
fromList[1,3,4,8,9]
ghci>Set.insert8$Set.fromList[5..10]
fromList[5,6,7,8,9,10]
ghci>Set.delete4$Set.fromList[3,4,5,4,3,4,5]
fromList[3,5]

Nsaindapodemosprocurarporsubconjuntosousuperconjuntos.OconjuntoAumsubconjuntodeBseBcontm
todososelementosqueAtambmtem.OconjuntoAumsuperconjuntodeBseBcontmtodososelementosdeAe
maisalguns.

ghci>Set.fromList[2,3,4]`Set.isSubsetOf`Set.fromList[1,2,3,4,5]
True
ghci>Set.fromList[1,2,3,4,5]`Set.isSubsetOf`Set.fromList[1,2,3,4,5]
True
ghci>Set.fromList[1,2,3,4,5]`Set.isProperSubsetOf`Set.fromList[1,2,3,4,5]
False
ghci>Set.fromList[2,3,4,8]`Set.isSubsetOf`Set.fromList[1,2,3,4,5]
False

Podemosaindausara map e filter parafiltrlos.

ghci>Set.filterodd$Set.fromList[3,4,5,6,7,2,3,4]
fromList[3,5,7]
ghci>Set.map(+1)$Set.fromList[3,4,5,6,7,2,3,4]
fromList[3,4,5,6,7,8]

ConjuntosgeralmentesousadosparaeliminardeumalistavaloresduplicadostransformandoemfromListe
convertendodevoltaparaumalistacom toList .AData.Listnubjfazisso,masremoverduplicadoscomlistas
grandesmuitomaisrpidoconvertendoprimeiroparaumconjuntoedepoisconvertendodevolta.Masusarnubrequer
queostiposdoselementosdalistaestejamnatypeclassEq,enquantoparaconverteralistaemumelemento,deveestar
emOrd.

ghci>letsetNubxs=Set.toList$Set.fromListxs
ghci>setNub"HEYWHATSCRACKALACKINE"
"ACEHIKLNRSTWY"
ghci>nub"HEYWHATSCRACKALACKIN"
"HEYWATSCRKLIN"

setNubgeralmentemaisrpidodoquenubemlistasgrandes,mascomopodever,nubpreservaaordemdos
elementos,enquantosetNubno.

Fazendoseusprpriosmdulos
Temosvistovriosmdulosinteressantes,mascomofazemoso
nossoprprio?Quasetodalinguagemdeprogramaopermite
dividirocdigoemvriosarquivoseHaskellnodiferente.Ao
escreverprogramas,umaboaprticajuntarfunesetiposque
temomesmopropsitonummdulo.Dessemodo,vocpode
facilmentereutilizarfunesdeoutrosprogramassimplesmente
importandomdulos.

Vamosaprendercomocriarummdulotendocomoexemplo
algumasfunesdeclculodevolumeereadeobjetos
geomtricos.PodemoscriarumarquivochamadoGeometry.hs.

Dizemosqueummduloexportafunes.Aoimportarummdulo,eupassoapoderusarasfunesqueforam
exportadas.Ummdulotambmpodedefinirfunesquepossuemchamadasafunoesinternas,masspodemosvere
usarasexplicitamenteexportadas.
Noinciodeummdulo,especificamosseunome.SenossoarquivosechamaGeometry.hs,nossomdulodevese
chamarGeometry.Especificamosasfunesqueseroexportadaseentopodemoscomearaescrevernossas
prpriasfunes.

moduleGeometry
(sphereVolume
,sphereArea
,cubeVolume
,cubeArea
,cuboidArea
,cuboidVolume
)where

Comopodever,calcularemosreaevolumedeesferas,cuboseprismas.Enfim,asprpriasdefinies:

moduleGeometry
(sphereVolume
,sphereArea
,cubeVolume
,cubeArea
,cuboidArea
,cuboidVolume
)where

sphereVolume::Float>Float
sphereVolumeradius=(4.0/3.0)*pi*(radius^3)

sphereArea::Float>Float
sphereArearadius=4*pi*(radius^2)

cubeVolume::Float>Float
cubeVolumeside=cuboidVolumesidesideside

cubeArea::Float>Float
cubeAreaside=cuboidAreasidesideside

cuboidVolume::Float>Float>Float>Float
cuboidVolumeabc=rectangleAreaab*c

cuboidArea::Float>Float>Float>Float
cuboidAreaabc=rectangleAreaab*2+rectangleAreaac*2+rectangleAreacb*2

rectangleArea::Float>Float>Float
rectangleAreaab=a*b

Aboaevelhageometria.Mastemosalgumascoisasaatentar.Comoumcubonadamaisdoqueumcasoespecialde
prisma,definimossuareaevolumecomoumprismacomtodasmedidasiguais.Aindadefinimosumafunoauxiliar
chamadarectangleArea,quecalculaareadeumretngulobaseadonasmedidasdosseuslados.Extremamente
simplesjquepuramultiplicao.Percebaqueapesardeausarmos(comotambmcuboidAreaecuboidVolume)no
mdulo,noaexportamos!Issodevidoaomdulotratarseapenasdefunesdeobjetostridimensionais(masqueno
deixamdeprecisardarectangleArea).

Aocriarummdulo,geralmenteexportamosapenasasfunesadequadaseessenciaisaoseupropsito,deixandoas
outrasinternas.SealgumestiverusandoomduloGeometry,noprecisasepreocuparcomoutrasfunesalheiasa
seuinteresse.Podemosdecidirmodificaroumesmodeletarumadessasfunesemumaprximaverso(comodeletar
rectangleAreaesubstituirpor*)eningumperceberiaamudana.

Parausaromdulo,sfazerisso:
importGeometry

Geometry.hsdeveestarnamesmapastaqueoprogramaqueoimporta.

Mdulostambmpodemassumirestruturashierrquicas.Cadamdulopodetersubmdulosquetambmpodemterseus
submdulos.VamostestaroconceitoparaqueoGeometrytenhatrssubmdulos,umparacadatipodeobjeto.

Primeiro,criamosumapastachamadaGeometry.AtenoaoGmaisculo.Nela,teremostrsarquivos:Sphere.hs,
Cuboid.hs,eCube.hs.Oquecadaarquivoconter:

Sphere.hs

moduleGeometry.Sphere
(volume
,area
)where

volume::Float>Float
volumeradius=(4.0/3.0)*pi*(radius^3)

area::Float>Float
arearadius=4*pi*(radius^2)

Cuboid.hs

moduleGeometry.Cuboid
(volume
,area
)where

volume::Float>Float>Float>Float
volumeabc=rectangleAreaab*c

area::Float>Float>Float>Float
areaabc=rectangleAreaab*2+rectangleAreaac*2+rectangleAreacb*2

rectangleArea::Float>Float>Float
rectangleAreaab=a*b

Cube.hs

moduleGeometry.Cube
(volume
,area
)where

importqualifiedGeometry.CuboidasCuboid

volume::Float>Float
volumeside=Cuboid.volumesidesideside

area::Float>Float
areaside=Cuboid.areasidesideside

Perfeito!OprimeiroGeometry.Sphere.VejaquecolocamostudonapastaGeometryedefinimosomdulocomo
Geometry.Sphere.Fazemosomesmoqueoprisma.Percebatambmqueemtodossubmdulo,temosfunesde
mesmonome.Spodemosfazerissoporsetrataremdemdulosseparados.Queremosusarasfunesde
Geometry.CuboidemGeometry.CubemasnopodemosapenasdarumimportGeometry.Cuboidporexportar
funesdemesmonomequeGeometry.Cube.Porissoquefazemosumaimportaoqualificadaetudofunciona.

SeestivessenumarquivonomesmonveldapastaGeometry,podemos,digamos:

importGeometry.Sphere

Eentochamamosareaevolumequedevolverreaevolumedeumaesfera.Massequisermosusardoisoumais
mdulos,teramosquefazermalabarismos.Ou...fazerimportaesqualificadas.Entosfazemosisso:

importqualifiedGeometry.SphereasSphere
importqualifiedGeometry.CuboidasCuboid
importqualifiedGeometry.CubeasCube

SchamarSphere.area,Sphere.volume,Cuboid.area,etc.equecadaumvaicalcularreaouvolumedoobjeto
correspondente.

Logoquevocseveremumarquivomuitograndeecomvriasfunes,tenteperceberquaisfunestemumpropsito
emcomumeestudarsepodecoloclasnummduloseparado.Vocpodesimplesmenteimportlonaprximavezque
umprogramanecessitardamesmafuncionalidade.

Funesdealtaordem ndice Criandoseusprpriostipose


typeclasses