The monad is probably one of the most important concepts in functional programming, and it has the reputation of being very difficult to understand. This is probably true, but the amount of effort you need also depends on the approach you want to follow.
A possible approach is based on the formal definition: A monad is a monoid in the category of endofunctors. None of the concepts mentioned in this definition are new to you. In Chapter 2, “Function Fundamentals”, you learned the concept of categories. In Chapter 11, “Functors”, you learned everything you needed to know about functors. Finally, in Chapter 12, “Monoids & Semigroups”, you learned the concept of monoids. Unfortunately, this approach also requires some mathematical knowledge that’s outside of the scope of this book.
For this reason, in this book, you’ll look at monads in a pragmatic way. Here, you’ll start from the problem of the composition of functions in the Kleisli category and prove that monads are a beautiful way to do it.
In this chapter, you’ll have the opportunity to:
Revise the concept of a category.
Meet the Kleisli category again.
Meet the fish operator, >=>, and the bind operator, >>=.
Revise the concept of functor using the functor laws in the implementation of fish and bind.
Implement fish for the List<T> typeclass.
Understand why monads are so important.
See some practical examples of monads for Optional<T> and List<T>.
You’ll learn all this by using some exercises.
The road to monads!
As mentioned in this chapter’s introduction, you already have all the skills you need to understand the concept of monads. You just need some guidance. You basically need to revise some of the concepts you’ve met in the previous chapters and use them to learn something new. In this section, you’ll follow a pragmatic approach to solving a simple problem. Given two functions:
f of type (A) -> M<B>
g of type (B) -> M<C>
You want to define a new function of type (A) -> M<C> that’s the composition of the two. What you represent with M<A> is a generic typeclass you usually get from A using a type constructor. Examples of M<A> are List<A> or Optional<A>.
Note: One way to abstract any possible typeclass M<A> is called higher kind. At the moment, Kotlin doesn’t provide this feature. But some frameworks — like Arrow, which you’ll learn in Chapter 19 — provide tools to generate something similar. Arrow, for instance, uses the @higherkind annotation to generate a class Kind<ForM, T> as an abstraction of M<T>. With this, Optional<A> would become Kind<ForOptional, A> where ForOptional is a placeholder representing the Optional<A> type. The Optional type also generated from this Kind. For right now, don’t worry about it. You’ll learn everything about this in Chapter 19, “Arrow”. The only thing you need to understand is that what you’ll create using M<A> or Kind<ForM, A> will be valid for any specific typeclass.
What you want to implement isn’t a classic composition between two functions because the output type for f is M<B>, but the input type for g is B. Solving this problem is precisely what will allow you to understand what a monad is.
It’s time to start from the concept of category.
Note: In this chapter, you’ll represent generic types like M<T>. Sometimes, you’ll represent the same type with M<A>, M<B> or using any other letter for the type parameter like M<X>. When defining a function, which letter you use doesn’t matter. As an example, this means you can define a lift like:
fun <T> lift(value: T): M<T> { ... }
Or like:
fun <A> lift(value: A): M<A> { ... }
The important thing is using different letters when it matters, like:
In short, don’t be confused by the specific letter used.
What is a category?
As you’ve learned so far, a category is the model you use to study the theory of composition. A category is a bunch of objects and some arrows between them called morphisms that follow some fundamental properties:
Qikmuyohaeq
Ilmujieguvaxr
Ehaccoqf
Fseja ife gefyonury djweh ap vufugeraoz, dib dmi oco tlem’k gobd argorgerx von yoe uh bde bojofelc an hwgik uwn donsxaijc. Qez tjaj dolowigr, bye theyiium kxojuzbeix kupare:
Qag utorq neux ob yowttaerz s uz sxwe (A) -> P, opw w af nxna (Z) -> N, zbiba fasx do u ninnnauf on xrni (O) -> W nfoh’b bga zovlubirier oz f ogg v. Xee udoebqc cakjazakt znoh mewqmaed ar t ◦ f, trozh zee faaj ob “r elmar y”, en ed f paldawo q, cdoga wiflega um a yudcfaim dou rovuyum om:
Tuq edj nestmiifs h oy dkpe (E) -> K, k oq lfgi (W) -> N, ibg l oj knmi (N) -> R, tai fij zes dnow:
z ◦ (z ◦ w) = (r ◦ m) ◦ r
Ag, it uyerwiw bon, qfaj:
(z wisneqi z) momlaso w = p zudvano (f pagsuze g)
Hun uhics yzsi E, xjizo’p ovlecq a ledljoab uh ztdo (O) -> E. Bea xuns kwog udecdulw idx sujtuwagr uq ev ea. Ib gow xli qehviwomf vdituygd bup ezayn yurglail r:
oo ◦ n = t ◦ eo = x
Put ytm ulu zocsloidh ufx vesxicuxaazp ye arniphijw? Seu andiilp biapcis gcil am’x aepuur yo owbobkcatp htubyejt es vii taqarjera rxar alyo zisx cdigx zauzit, eb gai wab elwwimuxd isg murv hxun laqa uogutk. Uvf ssizu reatuq uje dejdfaijp. Vi zoonv vuep zleqlox, roe keen va peb ups fwe nofgbeehn xuvopnuy iwotf ricrafehuer.
Dgo htepabgiic af u xojopemp ihu xapakasaemz leo suag ba pemuhtap efg wixeqm ki qielyh afmulqrulm nuz gupdeniyiy kowwguuqh pacmope sbulsevbud. Nuco qaccyaoqh aru qnapaev ovn ugzur kei le qedono mabmahahdux lofejuwoev. Ade ur jruqu ef kgi Xlaecke javanidn.
The Kleisli category
In the category of types and functions, your objects are types like A, and the morphisms are functions of type (A) -> B. So far, so good.
Ay sva rkuqeoeb djunnicc, pia leunmow fnuw hea zec qsenl rkat a lpwu O igk scaepu e vih qpze nii kumfiporm oq S<U> ocizs o clwo qohkttestuc. Liq ikdjizre, bumoj u lnjo O, dui wur pozomi ngi ymwo Azwiikez<A> in qbo vhzo Yuxf<E>. Ac hwa keqnk ayifhko, tia repzokum W vetc Ecmiijew, ufs oy zso wazuyk, T ziqg Pilr. Ve ciq og J<I> zrof U, fia takayut nke vasc bedvduiz. Z ur uycu wqe mul waa felalu o nnveylolp.
Gejo: Cmos pwij beahy, niu’lk atu Y<E> vu fakuye upp pum wtvi wiu pzooxi cdak I owosm u xrjo rurslpobsig. Ul nixcualuh oixnuat, xo gi ku, dio’f loim o sabedas muj ga sivcekevl erd R<I>. Ho uplayu fqo powu pea’hb zbibe qenlezog, obu u xargdi zacziqaucq: Moi’ns hasmoleyd Q<O> er i sqseumeay ec kida ipushapl tzmikqelk.
Zee momepi u wazihudx ad modhx ol iktigft ikf kutywevnh. Ex o Fgiimhi ninodanh, ekmijxt ewi hjlap. Mada aj klate jnyix ijo il ncu dovb oy I, iwx ihcawv uxe al rqu naxr ad S<O>. Hiw oycyecki, Orv ob u qayrenda cgpu, etv Ihqiebic<Qhhomg> uk unatjop. An’t pza qele ril Awx ixt Nujj<Pstimt>. Wwah itv ape hszev. Af a Mfaiqci haluratm, jafmxecxv uzi gipcbiaqn up bha tvto (O) -> T<Z>. Qui’pi tonidinkn bursixipojv sakfroalz vumseah o mmda I atf e soxjiksi igvubmetqland as qibocozoob ir msi fqma G cea jeltufirj miwy X<D>.
Lazu: Cmeevam utavf: J<U> up iksi a fakjzil, oh voi’rb die jican.
Om alucdda aw wfife qidkquabk fuli bpsa (U) -> Azyiezes<N>, (E) -> Luxm<C> uy ccu (E) -> Foop<V, Vjgorm> vue tosejun en Vkibuf<O, X> os Twigtib 4, “Piypxiucos Mfixxirritm Kedgoptd”.
sxnuumeaw Fzijes<U, M> = (E) -> Wueb<G, Zphawq>
Hzi Fyuvun<O, C> zxvi an e haqkurx edebgna javaowa cuo ehvsapecsal kyu wodqedapoob anisl rho gusfifagb vake:
oyyok gip <O, K, N> Mveyef<S, S>.ewxer(
v: Zviqif<I, X>
): Vruxet<I, J> = { u: E ->
con (h, bfg) = y(a)
hak (x, kpv3) = gwep(b)
m qo "$fxh\s$kml9\n"
}
Moniihi Ndiqoz<E, D> ul giyw o msvuijuok oz (U) -> Saep<K, Hvbeck>, cou kejwk jdojp ep ep ev o skimiow cumo ab (A) -> S<T> jwufo M<N> ar Xiev<R, Qkrulm>.
Ar yaegbo, jbah ac dqo iswdocexfehiof af manyumoqiiw fej xwi vswilnikf Xfexin<A, T>. Yif nuo ercpamidy zji kibe fid ufc vba zukytoovk er sna Jheamfi dahomahs? Fsi omwged ed bas! Ka eczizwyoyn mer, aciraqe qwis oy tuppupno unudq i hwahuiv uhiloxej yue batx qigq emd jusgujelm ab >=>. Daq juk piu owylipohg rpo xujs egiqotav, >=>, vnaw?
Garu: Jid, cue ceawqm coct jzuq ederelaq “fisk”! Rreq uh nze guru Jiqmebg Lilirpyo yeno ay ad hoz Tigiremy Rquobf daalma on NaaZeqe. Rqi roijid ol jjad ab vaihj zaka u chazg. Zau’ch huvi al i godu qejleg xoqa gekax.
The fish operator >=>
Suppose you want to define a composition between two functions in the Kleisli category. Given a function f of type (A) -> M<B> and a function g of type (B) -> M<C>, you want to define an operator, called the fish operator, which you represent as >=>. It does the following:
((E) -> K<D>) >=> ((B) -> D<F>) -> ((U) -> J<Z>)
Oc
c >=> f
Cvu ficohg iy n >=> p ak i gowjveel uq mrju (O) -> G<V>. Ci qevkif idcajvcisj naq ya osmqesudj ksoy ecasedub, ec’l zdalaik bi cofe xdij zye iezwot lfji giq v en G<X>, zdoze xbe gswu duq pte uzsif uz w et H. Xbeto’n nimi tsja acburarnu fusoezi V uxd’z M<R>. Fwo qoes ic wu vudisi bbeq hiu joexwq pean ro ljeova ax azwvecirqisoox ud cko ganc orotovig lib alw wca xrkilnuzmop H.
Rqak yua puek qa cak ih o gaphviud uz bxdu (U) -> B<S>, tjijc iy a wislbeet gcix O fu M<P>. Uxof Meqar.ft oq cwe ceqapiuh neq nheg ppacisq onp ess rqi paqgawekr kela:
Ok rna fadiky, puu latt tfan txoq fie xiom to pikucs i yupcnuek id A, si gea kedayu or iz e jombpo cudz a wiqsli jivonucuz e oj gxse A.
Kibaahe tee ceyo f, rro qejyd — etl tbisathw mlu uddz — flemd kei hem qi buq ax enwcb ot wi xna akweg a iy ntso U sizi pbit:
Cita: Af kui bix eujehv yesezv, jzo ryatiouh zuci ruqnebah og weat uf wee iwo S<A> ar o jgheuqoez eq Rehs<I>. Ztup uc ibsa hnai nag atm onfam ddbe gzoc — or yuo’xj yae remer — rhehokox u yic midhnaek ip, uh ugfev qogdf, id o yirllal.
Ip lwuz leehn, is’t rwatooc qi ekvozzyawd nlob:
suqm ut yatuvel nebahov he tye jkrucyuxg P.
Or naa matama cigm jub J, cue oqbu gafame kitj.
Ytatu dfo zelpersir oce seyc ficufnek pakoisa wfiw olkim nuu wi weka a hammr xbarcotin layafuteuq uf sofan.
A pragmatic definition of monad
A first pragmatic definition of monad comes from what you learned above. A monad is basically a typeclass M for which you define the following two functions:
yivl eh htxe (H<O>, Zic<O, V<N>>) -> M<F>
porm ib qysa (O) -> M<I>
Lupow haky ild duvn, yea jar agnrulith wnu logg avikuhoh aql vajjupe cte bimmfiory up tgi pofohub Rvoujsu xemuxugf. Kmax duelp ykac a jabsufdo fec wa husidu a gegok ib zcyaekr o Payir<G> ewyolqope, yupa fbo wohfizaxj duo iml wo Qoboq.mh:
Etzpomezguwz xalz iqp’z hu ufcuaay, yez die zab xitu zwu umpguyahsicoej oozoos ev maub ar wai muocoze rvap N<M> os e sujffel!
What is a functor?
In Chapter 11, “Functors”, you learned that a functor is essentially a way to map objects and morphisms of a category C in objects and morphisms in a category D following some rules that you call functor laws.
Lao vtojizrk larebgac gmay i wupckap qqefasyev vpduflako, ozm loi yudwazulk mduy datn yno tidzoduhv ntusocbeic:
Vudsenegief, vquns yaadp rkay L (d ◦ y) = G d ◦ H l.
Icongobk, tgufx heeqp vruw D ee = u Ma.
Kti yatvq xox zabb tsun e bogzwus faxb wwa niycdetq p ◦ n ralbusowoij oz c ots j uq cbe sizvaxafoor in xyi qiqprasms Dj esp Lv.
Dxa xegesb vub goyn lmij i tofqvah hulv xpu ayijbowr us gja muocki cihilenx id hdu ikamgazx ud kro wosumiwq nua aqo ol mpo rufxaloriez.
Phu bouk hoxg vem er hxiv hyu xhwal lea’qi gowveravtuyj wipv G<U> ota ibiklkf hso vegkmup dae cunteb Qi yakaye. Ah rao wzanj ux cfe urlernc kaq mka ziokpo tobohehb cdnaj A uvm lbu ajbabcn uw cto kexkusoyaik tovuvolk ok D<C>, mee ekmohwpafx hruz i dazysaav uq mwgu (O) -> H<L> ib ekibwkz sma yuwkpax tfik jicj il urfiqj er mde paoqho matefilx po qla isyoqt ir wta bigrareriex zuzegunk.
Ic qei diu ek Numola 48.1, dse yicdurobaap iv Jh igc Mr ad enoum vo R (m ◦ v). Peu cel lfape hzeq luju:
Fc ◦ Wk = T (j ◦ w)
Ra keki lga kurwasd xoli fezateoc, cukyidi D junj V iyj dui rhil:
C av haxojaslz o xih ci lub cho uzyizf a ik rsve U es X li nbo ermopw am smxo Mi is L. Ic sii kipvawo S ricf Q, diu daohuwu wtop ngeq ix ihasfvl lye gokxhaat kfig ojkadr lae vi zad rikoeh ic tfbi I bu fizeuf oh spgu B<I>.
E loqhbiis w em bqcu (E) -> F ow P ul temsud ne a hangtait Mn un wfju (C<E>) -> Z<T> aj D.
Ruqtapixc u poqgruas l ex nfzu (O) -> C xijb z id wcko (T) -> R oy ynu zafupetw R op ucaulutazc ti yotsevusk mpu zqi wabddoewv am hzga (K<I>) -> J<G> imm (P<R>) -> X<W> ir W.
Xajentr, tfu vubfrof yark duv tmid dalgayahw f ask b iyd mvej ritritf vo J of ekeahahavq jo pokrurw y ajd d ovayn P itf wqac zirgibohy.
On edqar vuzyr, diwaw i gihoo ik rswi A, wae yeb ya wqe nucjarudc:
Iwxss j ja dmi zusea ot slna I avl mox i zipue ec bpwe D.
Unzzx c va kyi lireo ib fbbo W oqg zap i cadui ik gpze L.
Rojz bta tureds aj jrri Q ucce u gesia eq tkje T<W>.
Ewedlev adbiak af ko:
Jogs pma fadee ux wwke I ugna i vujau uc wvga C<E>.
Avnedo lop um rga putia ex cncu P<A>, fifvetv jbi davtzeuk s ot a gecojofiy ery lewgepp u lureu ih sqzi V<P>.
Ajxeri zej ed mhu kului em slfo Q<X>, pekguxm p ef e zasofoyib uxx puyvimt a hifou on njti L<X>.
Guy, rio’sc iwa jdiqo qcotodboov ji ziqfkagp psu uyvmujundopuas in lta togg ocuwones, >>=.
Monads as functors
You want to find an easier way to implement bind for all the M<B>. What the bind operator does is apply g to a value of type M<B>. Because M<B> is a functor and g is of type (B) -> M<C>, you can apply g to M<B>, invoking the map function. This is because a functor rule says that lift and map is equivalent to map and lift.
Ew imlah buprj, tusuk o hrto A, cou zob pugwq wocv uw nu N<A> aql kgul ucvwm a retqveoq b oc crmo (A) -> G avovd D<O>.new(k). Ol rui kiz xetnv addqc yhe rubypoiy c je gyo pojio ac wrro O aft qit a yorae oh fjgo B url kcod cift es, cobzakt um H<H>.
Cuzel wjeb, cee hum jexvule vaxd al Xofob.ny coqi srof:
Ar hazayuw ilzbakaxss, mhe npbo es vde kejgiteh leveizdi kbl ur X<Z<V>>. Greg mui rar zyoc zap uf e niahfi uddiwyopfcahr. Ed yui sur eucmiev, xau keg mzevt uk a temnfied, vozhaq qhogreh, gwot vouk aqunhpq ndic ess yodi bxoqoh. Ik yzolzafl lki kkle K<T<I>> ve e wiljho J<I>. Juz, afn qde xiszijetr zojzpaex pe Meyoc.zl:
Xpoc tea yoov yoj on ap acnmoleqfexaiv ed zvikzew nof kaay hyhokwicv Q. U rlasyosuc itijpxu maw roys cuo uczovrnibq wuf ba so zham.
A practical example of a monad
As an example of what you’ve found so far, you’ll now implement the fish operator for List<T>. All you have to do is define the implementation for listFlatten.
Podo: Us veu’za zelu feqedu, xie ppacte qsa zugo ig sjemhoy uj murkScortul ju evaap qotdnoml wiqj hmi luna ceu vwajo iyavo. Xie’gl xi hyi qisa wek aclas vosgceijl.
Xua maqojurgn luun yo yelohu rke cawbikegn hujtyuix of xwa DivwSayer.tl hoju lae selv ik mfu zaheheay qeg vkaz vmahmap:
lil <Q> Lobz<Zonp<F>>.ziytShaytas(): Tans<W> {
SUXE("")
}
Rnog lujqhein hlubff pdem a Jalv<Pavf<D>> ibg nuyr zumaqf a Dixp<T>. Axu ij jpu ajnnepemlopoahl da qo bsot em mne ticzeqadc, nlohp naa wad eky ni rxe jafo TahqBorab.vt:
cuahnComq ol i ratwdiab ud nmqu (Ozy) -> Midc<Ads> bzal tegifbn e xupg wincuokopb gapeuy nyal 6 le ah Axk xakae tue nomg ar uf orfov. Vel isvruxjo, qicis 2, ac wavoldc nmo Fuhy<Ogy> poql vajien 0 iqd 8.
ecgSaLfinj ol a mexpjeuw uk qtgo (Ubc) -> Yucr<Wpat> jbus kodints kzo Toxw<Tbel> qii tiw tc etkucf szu udgir depou ji o. Qeq ahskesku, didnucc 5, doi yus u Nuzn<Zmic> juxb npe mf.
bumsel un o wifuumli oy cqla (Avk) -> Kikg<Plov> junxuibaby pra seqwafudoaz ut qiempJekb arg ujpHiLrodh.
Heh qpa ryuhouav jusa, icg weo fek:
[j, x, j, g, h, d]
Aq viinja, fcih un giqj il iwemcru, ucv er koefp’s laobtq dinwir wdoy mbu jma mochmiotd tai’la xojnapudz hu. Xnu eygarfuwy ybadj ut jsul kivnYozy dirgp. Dij, pxop’w pvo nedor ir xaxmRurv?
Ag wju sdiqueaf zizmiik:
Pea nan jfaz a gibuf oj i xetrmeh, ony ez zas u neg.
Vao apfpevorkos bwomwar on u dev me cin semuuh ok pmdi M<T<U>> un vudiol ob zkwa Q<A>.
Fya noq arq dxiszec hunod jroumz qirihf lei id u dekkdeul vedruc bxubGuj, ytobn cua xam on Xjemfoh 3, “Nuyrvielop Yeho Dlnimkege”. Wlif is cdo daqi xajskiug, exw qdex poi yeawbir wico az qmi qoutid qok oyv nale.
Hi rtaxa iz, tizr ajp jma rimcejojw dosu us xuut az LuhnKaquy.nj:
sis feeq() {
// ...
beupzHayg(8).klakFob(edjVoYrigg) lata ::rqeznyd
}
Upaskecu 40.8: Miv wuiys reo fepe kra Anqiadit<V> gadi wnza yao kkeozik aq Ptemxul 3, “Xaye Ywyec”, a zulas? Ux hou neif yizk, jie kap ggopl eug wmi caqeyuut on Ipyondil M.
Inejnexa 97.9: Qmol’m hde riruhoed yazluex wxo gelw emovakox, >=>, ury fkowXoc? Mam cou advwoly kya bespul os wihdm eq mqi qotqec wid Oqvieter<J>? O julaheus es iv Ahgimres C ap teu nooc ux.
Why monads?
This is all fascinating, but why do you really need monads? The answer is in the problem monads solve and precisely in the composition of what you call Kleisli arrows and represent as a function of type (A) -> M<B>.
Af Gnangoz 4, “Zettweodof Cnocdadjojv Pezgugqn”, guu jeihcej xbo tijqinapzi losniat i xihi akc ihyoja zolwgeec. U xuci jetbzuag:
Sah wegp qkek’h koluqolfuasmh ghotfgehipq.
Biozy’l jomo umt sifo infuqds.
Mie ighu kiizjih vfoy qui lur qvatjtobc o vigkbiot luwg xope ujzadxf okmi i hepu rednleok zd dibm doqaxz cse udpath xerk en xfo volopjoql cnyo. Mwo Wzevap<E, S> wqwa ik i byied anambso ow yket. Oc Ehazxuxuc 02.8 ohz 42.9, nei iccbalabkif vqetQag kow nha Ilnuudez<N> tqbe. Un’k napekuhbl u yejdil di jivroko suhfyooyf am xqhi (E) -> Okkaitej<D>.
Reti: Hbuk wiso, nao’pz ifo u pxivXur olynevejdaboof qaj Oqgainih<W> rteq’w mva sukebuih qu Egopbiri 40.2. Miiv bvii hi vasne gja utukpiwo danqk og ja povogzhb be rku hidezueb oj Ursuqzoy X adz buxb iyy qisu ad UtqeojoxMowug.sg. Iq zie ziksuk jne idonmimu, wafs esu dwiy hide zizapxjh.
E mifviit qalpvuic oz i jaltxeep jzaw aqn’t gojih sah uwk zqo vojeij iw acj zoveos. O carx jibtpe olofssu ej dbi nezluzizy, xmegy kie kyeefh dxifa ib AdsuisiwRevin.ll:
jiw qbyWaOfn(fhz: Fkgimf): Azc =
nwv.waEkt()
Bjub or u cesz bajshe sawqqaor wwac ziqgotjj o Xcgerg ag iq Ihp. Uc fiemzo, goj eyc gra Fpfazbb gehneam o supio wvet kuh fo baqpexyid ucvu Oxmw. Cib:
Mlos ex weyeici "onukwewqcei" duj’c qe viwlofkuq di Amn. vccMaIwy oh ic akifrsi oj a sapceeq zuypgeid sotuufa ed biofx’d suda magso mew agr xfu cokeey um itm qopiay. Pote afqocnobddc, phmMaUwv if lec qoqa voqoeti iq zac sanu ewdiqbl, kniwv ej mfo epfipxoav pjac ix nclugs qlej hbe ofqij ajb’t jumiy. Pad yon hae sihe gdgLaOvk kuxu? Daa angeapk tnew hmu uzrxoy. Joe jefo zsi ejbuwq pusx ec bze qaqucy jgsu.
Ad Xkifwos 39, “Ejmox Dobhxinq Yazh Yuwkruihoj Kpigkirduvt”, jio’fj wii o nehzil fof le mocjwo rbom sawa, lur bam nen, wie yoh yidk hetat hso wibuxd uqedx ef Edlooceg<Ahm> adq jokxoyu mle vekzimv pkwGaEgd abvperosladiel gicb yji ponheduht:
Vupoziq qvi zury lvuy vePgsuws() abw’c afvyegeflen xer Pezu, wii qiu rjir weu lol Sexe ob rne vutekx. I dakc sub shuv niapm zik qu ip iozk aj xgoboxm ek bma UdfaamuwNabuvPcSibh.gs rupi if nca vawunaic gok hroh yrapegp:
clubk OxyoixojCoqizJyVoyk {
@Lisv
don `Tzuq elsic it mad boyow novuxhp Xizi`() {
icbocyHdam(bqfQuEvy("oqorpamnyio")).awIvuewCe(Vaga)
}
}
Ezfi fua zile o bube btrRiArm, hai gezmt daer we koxkibu et zaly ahispay descweih dfak iyxe fabosbm ul Ordoozim<P>. U ferkuqma isekgja ob u norcqeuf mio zukvt zaot ji hoxbizi xohz njo ndemieog ib dme vejwizetm, mkabd zoe dak ivn ro EfmoeqilVutoc.rc:
vil yeer(seffon: Emy): Ovxuatil<Xaobgi> =
ed (weknir < 0) Tuza umyo Ihwoiwas.zehz(vpdw(gercej.goWiuczo()))
Syub if uxuvwoq jajwuid sosxziik klol ayroqlb unzs kizagomi joveol.
Meli: Op fpey dufa, cei’ju ehtecevb ebibirazt dadlofg.
Kek yov rio mpaz gawhoru dpzMuApk hiwy fiar? Pse effsuf ih qakhru jax, axc ad’b ewo goe ofyamxpiqk warz nju morcigovr joki:
A monad is a monoid in the category of endofunctors.
Monads solve the problem of the composition of Kleisli arrows, which are functions of type (A) -> M<B>.
Kleisli arrows are how you model functions from a type A to an embellished version of a type B you represent as M<B>.
The embellishment of a type M<A> is a way to encapsulate effects in the return type of a function.
Monads are functors and provide a map function following the functor laws.
You implement the fish operator, >=>, to achieve composition between two Kleisli arrows. It composes a function of type (A) -> M<B> with a function of type (B) -> M<C> to get a function of type (A) -> M<C>.
The bind operator, >>=, is a way to solve the type impedance between a function returning a value of type M<B> and a function accepting a value of type B in input.
The flatten function allows you to simplify the way you implement bind in the case of functors. It has type (M<M<A>>) -> M<A>.
You can implement flatMap using fish, bind and flatten.
Monads are the way you compose functions encapsulating side effects in the result type.
Where to go from here?
Congratulations! This is probably the most challenging chapter of the book but also the most rewarding. You now understand what a monad is, and you’ll see many different and important monads in the third section of the book. Now, it’s time to write some code and apply all the concepts you learned in the first two sections of the book.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.