Monads as containers/is

From HaskellWiki
< Monads as containers
Revision as of 11:35, 13 August 2015 by Bjartur (talk | contribs) (Draft: Icelandic translation of Monads as containers)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Mónað má hugsa sem klasa sem heldur utan um venjulegt gildi ásamt auka upplýsingum. Auka upplýsingarnar eru mismunandi fyrir hvern mónað. Fyrir Either eru auka upplýsingarnar eitt Boolean: annaðhvort Left eða Right.

"return" er smiður (constructor), svipaður og "new" í Java. Hann tekur venjulegt gildi, og skilar hlut sem inniheldur gildið. Return ætti heita encapsulate, vegna þess að hann pakkar gildi inní hlut, og skilar hlutnum.

return :: (Monad m) => a -> m a

Klasar hafa aðferðir. Mónaðar útfæra að lágmarki eina aðferð til viðbótar við smiðinn. Hún heitir bind. Í praxís er samt auðveldara að útfæra bind með tveimur aðferðum til viðbótar: map og join.

Map aðferðin þiggur fall. Map tekur gildið úr hlutnum, beitir fallinu á hlutinn, og pakkar útkomunni í nýjan hlut.

map :: (Monad m) => (a -> b) -> m a -> m b

Join aðferðin þiggur nested hlut, hlut sem inniheldur hlut sem inniheldu gildi; og sameinar í hlut sem inniheldur gildi.

join :: (Monad m) => m (m a) -> m a

Bind, ">>=", er samsett aðferð. Hún er svipuð og map, nema í stað þess að þiggja fall sem skilar gildi, þá þiggur hún fall sem skilar hlut.

(>>=) :: (Monad m) => m a -> (a -> m b) -> m b

Fyrst, þá beitir hún map. Map skilar hlut sem innihaldur úttakið úr fallinu (a -> m b). En þar sem fallið (a -> m b) skilar hlut, en ekki bara gildi, þá skilar map hlut sem inniheldur hlut. En þá notar bind "join" til að sameina, eða fletja, hlutina.

(>>=) xs f = join (map f xs)

Auka upplýsingarnar sem mónaði heldur utan um eru mismunandi. Fyrir Lista, þá eru ekki beinlínis aukaupplýsingar, heldur fleiri gildi. Map sér um að beita falli á hvert stak listans, og pakka stökunum svo aftu í lista.

Stöðumónaðinn, State, geymir stakt gildi ásamt stöðu.

Svo er líka hægt að pakka gildi í hlut án þess að geyma neinar merkilegar aukaupplýsingar. Áhugaverðari er hlutur með aukaupplýsingar, til dæmis teljara sem hækkar í hvert sinn sem hlutur er tekinn í sundur og settur aftur saman (með bind eða map) -- án þess að geyma neitt merkilegt gildi. Til dæmis gæti gildið alltaf verið tóma tuplan (), án þess að breytast nokkurntímann. Köllum teljarann ástand heimsins, og þá erum við komin með IO () mónað. Mónað sem telur í hvert skipti sem umhverfinu er breytt (með I/O aðgerð).

Trikkið er að ef við ætlum að skrifa tvisvar sinnum í skrá með write, þá gæti Haskell tekið eftir því að seinni write skipunin notar ekkert gildi úr fyrri skipuninni. Haskell gæti freistast til að keyra skipanirnar samhliða, sem myndi enda með ruglingi. Í staðinn, þá látum við write skila hlut. Nánar tiltekið IO () hlut sem inniheldur teljarann "Ástand heimsins". Þá getum við passað að einungis ein write skipun keyri í einu, og í réttri röð, með því að segja að write skipun þurfi að vita "Ástand heimsins" áður en hún keyrir, og að þegar hún er búin, og ekki fyrr en hún er búin, þá skili hún nýju "Ástandi heimsins."