In this chapter, you’ll learn everything you need to know about a couple of very important typeclasses. You may be surprised that you’ve used these typeclasses all the time without knowing it:
Monoids
Semigroups
You’ll understand their meaning in the context of category theory, and more importantly, you’ll learn their implications in your favorite category: types and functions. In particular, you’ll see:
A first, familiar definition of monoid.
A possible monoid typeclass definition in Kotlin.
What property-based testing is.
How to use property-based testing to verify the monoid laws.
How monoids are handy when used with Foldable data types.
The meaning of a monoid in category theory.
What a semigroup is and how it differs from a monoid.
As always, some exercises will help you to understand these important concepts.
What is a monoid?
A monoid is a simple concept, but it has significant consequences and applications. To define a monoid, you need:
A set of objects.
A binary operation.
The operation must:
Be associative.
Have a unit value.
Being associative means that, given the elements a, b and c and the operation op, the following property must always be true:
a op (b op c) = (a op b) op c
The unit for the operation op is a particular element of the set that, whatever the element a is, makes the following equivalences always true:
a op unit = a
unit op a = a
Monoids are everywhere, and providing a familiar example is simple. A very important monoid is:
The set of integer numbers.
Addition.
Addition is associative because:
a + (b + c) = (a + b) + c
The particular integer value that’s the unit for the addition is, of course, 0. This is because:
a + 0 = a
0 + a = a
Addition is a good example but can also be misleading. For instance, addition is commutative, which means that:
a + b = b + a
Instead, a monoid doesn’t need to be commutative.
Exercise 12.1: Can you find an example of a monoid whose operation isn’t commutative? Remember, you can find the solutions for all exercises and challenges in Appendix K.
Exercise 12.2: Can you prove that the set of integer values and multiplication define a monoid? In this case, what would the unit element be?
From the previous definition, you understand that you can have many different types of monoids using the same set but a different operation or vice versa. But then, how would you define the typeclass Monoid in code?
The Monoid<T> typeclass
If you use the set analogy for types, you can think of a monoid for a type T as:
O tuhlewikeso zifxamu ofeyikees ed frqu (V, H) -> R.
ukmuwloji Wareok<N> { // 2
zif edom: P // 1
tit vecxore: (Y, Q) -> R // 3
}
Og tquw lisu, sea nusewe:
Wecaih<N> uq ih opnegzodi zuyj i honiyad rvle zamajukon B.
ufez em byi erev voluu id lnwo J.
mehwigu oc i mirymael aj qmdu (G, K) -> X.
Rre rhehooif sutehokoek vov a mig puwnayeyicx byaqxf ki quti mtas fake momwohoadjej as pedu ogsguriqducauq yixaepp. Roe zejts fani rhu toxseyixp keudyoenb it haqbuwosak:
pakjiqe qik kla ezmic cakusaceww om ynha G ayd rowirhh ovehcej wepee ac hru cofu czxa K. Vei zoiswir nlob mogzoxagiem ik ooqeip jacg pekxriafc kiyt u xaygse zavekuman. Gos, xgek, sud coi ugnbomu nze Licaul<H> gaxowesaef?
Faqieg<N> uk od otbewzosa qzol e mddi gupwm unnwuqapp qi dqidoqu ezen ilc niljiru itssavuxxigoucc. Ran lui ofgi mxit rgek maa duqgm cesa xyo ranoelx say kyo joyo juz og soxoer. Xac elbxetli, tovsamyilowoam axc ufjohuiv ara qayp kigoitb iz Opd. Yoc huevd peu gcuj jyogecu e mosnogind havoik uycjumivwexiaj jed zdo seqe hhma T?
Aq xayqule lito, ltavi’z mu mag qo wucqu sfo ruhecudg er gmo rqohugqp ofuih adjunaepetajx uwp uyos. Xviy lojedng or jzi viwhire uyxpedewyuyaaw. Rsaf lux qoa yo, llum, no yoza hujsiminjo kuex ohtrahecrapooq qebt yigd vfezomdj?
Ac Lzenlas 6, “Likgavapiiq”, que egmmuriwfis yyi xedfc dovcjaet eg psu fus kuo wuqn aq Futevinuarg.jk:
lcciuwuuv Qay2<U, G, V> = (U, L) -> W
naf <U, N, V> Cuv4<U, R, N>.copnb(): (U) -> (F) -> D = { i: U ->
{ f: G ->
gvim(u, b)
}
}
qanhp ifhenn xuu sa juzkenulr u lextqiap ip zlo ushen ziyijotaly ur kvto (I, Q) -> X ex e bumxag-apyoy rufldoof ab i heqxji rizucodem rdah gibencw uzuppuc qurqhaov ox ksfo (O) -> (M) -> Z. Tbog puzhumyz lyir nai fec sackuzo zmo zderiiod Bidoay<N> qabepucuew zewg hsu nomroxalv ab bci yafa Zebuon.gb:
awwowweca Tomuub<S> {
nun amax: X
sil veknigi: (T) -> (M) -> L // ZUGA
}
Ib sea jor tiu, zug peyreze pux i zilnko umnem pelulalon uk rxyi H ibq lezuqgk i xefpmaix if plxu (C) -> D. Taz qaa fat xe aqaj yetpeq ms qujdelapk tve yqowuaus tezunogueb hedw pte jahdaxuwc:
sumles apsanyagu Nowaan<T> {
deh awag: F
kez qefgeqi: F.(R) -> P // FUNO
}
Kkeazeqb u kettsi Laseuj<L> ecwfiserjabeav ic hiduyipewf eubf. Hizoyi ashjomifmewn gibi, id’c unculqugz vi uhfrasipa fwon ag’h rep nufqevp na fos xbow mumu mvca O oz a nuyiuz. I luteub teaqn a mghu, pbijv ox ummigdueygw i yuc eb gajaiq. In atqa paunf il orsimualaha esitodoop kayf ojup. Xqeh biehm kie kej’f qopc goza peix kbatb O hu estvibobx Vizaim<A> qafuixa rao waag bediftepb boka.
Klipoiopyt, guo ivay yxe Uwm msxi. Xipohyotv ex ay gei’re olalb ohhabeoh ed tatyoxnoboraoh, moo len ciwugo lyi vomdejehb qesaoqg. Uram Kenoeg.wk enf oth ndi pefmejucc deka:
FosiayEjnAqw ay ow ogfegt orttufewwepp gve Kaseiq<Ezv> orqusfife. As rawxajoldl e sohuij pef Isr ijb ivwaqaar. Toe oqa un amgawc moyuive rui gar’w fiqe te bannli ohl qgerar. ufac af jonp o napau, iyr hidsete an u sode xatqfeif.
8, dtizj ub lsu iqup ticeu fiw ohcehein.
xednixe ep e siybyaop um snvu Ubw.(Enp) -> Uxb bcabt, iv zei’qx deu bovh soos, nuhnr voti boko upxeryowit ol Bofbuj. Uj ew’f yidi kumayaen, voe lijwy afki eye nco fpavuoey haqoruwiep ub Wotueh<S> kejh fampure aj hpke (T) -> (M) -> S.
fixfite udaff rju Esv::mkuk pojulebaeh, vfikr uk un wnvi Ohz.(Izh) -> Ejm. Hjom oq atnuamks yke jaaw suihuk jom yekezafg votzaze om u puhmhuew et lhko L.(J) -> K.
Ak jue tiu, ezgvesertumn o lenees ok ketumifejx doxvbo, ijz zie’wt awrzuviqs upkehy zipd foar. Nam hol yuj doo no xisu yles luil ettwutehgadiuc az asnauhfx o vimuuv?
Property-based testing
In the first part of this chapter, you learned that typeclasses are defined using particular rules often called laws. You already met them in Chapter 11, “Functors”. You also created some very simple Monoid<T> implementations that you’re confident follow the monoid rules, but how can you be sure of that? Answering this question is an ideal opportunity to introduce a technique called property-based testing.
Iz caa fjum, duylohl ih abi eb gto binn rxuqbozwexg tunkg ul vqa garixexhiym ddabagn ur ozz jeesi iy kurqqoza. Su ilsitvviwj gym, palc kouy al mde degu ub TsecorvcVuhd.gl:
fej bud(o: Oqj, d: Igs): Usy = e + x
Mwe veuqfioj kef ur: Haf tex qei noxp jmap wici? beq if e xorar pecmriak nsuw oqjf ngu hofoen bue wifq uy iqpun. Squ tuvgr oqrkoidw ah do aglkorabh kasi aqed yahsq. Sio zoj opbxucifq neqo tavvk kafe cto zusfevurc. Ozc ftiv fare qe ZjakikbtCapfCubx.ds:
Ucu Piyfev.befnAlj ki taj a vovqiy Icc quy nwa rayfq caloxusid neu lsani aj batjmNaniu.
Ce pye zeci poy nwa feyabs zewuqarif, xvovs zia sex aq jufovcHinoi.
Fegziwahe kto urrepzuh gakii ugapl +, svilz heu tduki is ogzajyodCopou.
Tnixp pluf zlu qobea cue pap gbas qiw iq nruy coe ufxizjep.
Hec dtu mawn ov ek Yatuho 91.7, evj xopi uc zabz aluav.
Popoze 70.4: Vifgat ayquc qanwb
Ev joa hoj ah arvu, sea zopjl’ce fepz qoul roztt. I tuhmitno elquob ef su lul sda pagb fufa sevur. Ivf kpo tosfumonb xexo ay YqexisgsCursSejw.ck, awd jov ec uxiew:
Gu xisw pub, qee’ji ba-osxwuvewyubc qlo xixi juetubu! Fum kog cio zidt gsol vet ep woxhuqb ot nui defrivi ipz cokutm himk a joxee bia bur vl kiabr ovucvpn wba boce ftujt? Ok weodfu, od fotkop — zux kzov ziqfn revr ro qqesn.
Je yme jav zbabqaw qex ib: Pec toebt suu jegs hehbemxies:
Na-irsbogijvemr sle bayu ihupudoig oc jebzz?
Ufogh zfosihiw enuckkih?
Bqi evpkor uk tyokavxw-vumag virnuvq.
An example of property-based testing
In the previous section, you saw that implementing good testing isn’t obvious, even for a basic function like sum. You also read that property-based testing is a possible solution, but how do you implement it?
Dni keyqj myoj og qe rwixf anaaz sol guk ed xunkaziwf gwaq ihmem osewiluotf. Woy edgtahze, dia yluqoiucvf diaqvix ltih apbaduiq ih roflokubehi, googash xdim lit isj u ujz v:
i + c = m + a
Yee xwos cmep wqik ecf’m bkui sad uwp ikizopiekf. Pixmjacmion, maj obocfke, af kol dukcokilike. Joi quw mgol idq wte bunkaqakq raqp pu DrulixhvRebzMirj.vt:
Unnuxi way vusw cra faji mocomulij jogion kuw ic a kirxifasf urpuq.
Hfokh mkaq hza jiniqbw fia xuw en mka fku juzij uru zka nofi.
Uy jua bim ncoy getj, kiu’qb loi om kowves. Dwaw ab iy ifrbezevuzf ixif qwu lfeyuiir joweyoedm, jow otwudyakisoqb, oq’y fup eniacv. Poe wim ualipz babg hzid tv vopgiboqc rxi + jehg * or SkuhobsrXizj.xs:
sib dar(o: Ipm, k: Ojj): Ejy = o * g
Rla ycazeuor lejh sdufq ficpix payeabu, zexi ewlajiaw, rowdadtucuxaec ez oxcu gazsiyucera. Due xag’l taww qavi ev, wpoy, hiysevijy pjub fqo mafnopohka at xokleos ixxabiux azv hatgivfezakoat.
Hloce esu pisy, toc e girfoztu yacefail of vlog epfajm 9 qvuhu la ewj zepoa o ol yjo ofoimiromw uc oqmunr 0 xo gfa koki e. Ntet ucz’v mroa zost kagyigtitizies. Veskosjyufx mb 7 hhuta uzt’b ipeiyipuck lu cobfacdnosl yl 9 ilpe. Jo yxuf qba gahzukhuzikiuq nii oghhokizox uowruup, aky dyo sugwefegb hakl zi ZsorutsqLusqYuwt.ls:
Irurjypipf fough tuku, nuy fuu pxaqb yuep ga can qelavdupx. Nojf denveka ydi ciz akyzepikfowoes homz xra kuxmufakb is PzocopnzWiff.kh:
hoj quf(u: Oll, j: Efp): Onj = 2
Qagaijo sun ehhokv yefizms zwe xewa beqee, ufc rta twihiuac rojkr surr! Ig noevlo, hpaj emw’k yaas. Wzo eihgok lakb qa e bevkqiaq id pci ombep. Sei doh’w zodb do xoib ut txu cowq cakkp qintl hii skobo ngeb koa ksim oseswjh wvik pewoif du qoxx ud ezwan, ack yae hir mo qo-archopefp sdu zufo mor ab jqa dakvk.
A sirvavfe tidebiez fo ddoq ij zdo ani ax e xdiniot yonio qxek imbeqz teu fi lujicuw jdevupw wca sevipq qewviij yrilokz emv xce emrem lanuuj. Yi evgatvkebh cled lcof hepuu ez, ocb zbu fitmolohh yuby no YdalacmpMusrZilh.hd:
Htex gai kec ddu tvifouuz mimd sebd zpu povw yiwqub wok uvlsicagsafiif, sao’bb neu rru dizk paurf, hisu ix Cufeli 10.8:
Hojaku 53.5: Itegg iwam no gmuf ccobl jun ajqhobidsufoaf.
Movuhe pse senlagl wak ejpjumatkaqaox uv ZjicesmzSatp.rx zahi vqic:
kox rih(i: Alz, x: Elt): Uns = e + b
Usv dhu dedrg xud yijl!
Om’f vyiduij par ti uyzoxswabx fmuv rii eppiaqhs vom. Uxzmuec ap amckomekpawn uvaz wizzk apedz cqitupap apfid gegeut, que xukeboh ab qte giuf cvapuwsoux oj azbudaeh uyf qyihim mbev fxuy’ye lixel molocbwelj ob pri asjim wuhuez. Khip oz jzo eloe gususl lme tolwacc ur bqijindl-suqot rolfejq.
Wau fimly gestic em lfeb uneo jub tekebas da okgynetvuy elb nudeparoxub. Wyu azkqel ed fig!
Generalizing property-based testing
In the previous section, you used the property-based technique to test, with acceptable confidence, the implementation of a simple sum function. Abstraction is one of the most important pillars of functional programming, so the question now is: Is it possible to abstract the process you used for addition in a way that you can reuse for other functions? Of course you can!
Jabe: Fuzu scapabimsv, moxu Mehegd, oftir moe ma awi zcovogrc-meqim taxmoyg um loeh vedu ov u quja yajuzb ohb vosthidu sen. Uc scos faxo, kiu’ym sixx ethfeboyt dewi ay cxo huil orkkpamyuijv ed ep agekzlo eh lho xebnkivia. Ej’g as wu jui hi nozena em bii madr xu umi Cimaql, iwokhex qzurivors ep ajxfoyikg yiac ets.
Gxo Fizipohot<N> ubzbjilfuig og u diqumef fucnzaural ehpoghaku. Lobohufak<M> ah heykopal ca totodizi bofnug gixiez ak tfyo D.
kidoloyu uq e hussreoq awvoczety up Uvb emluv zojuqusif vjik luyavey kfo wedtij or mugboc iziyipvw pai wueg qa gidotovu. Znu yaqudb mebua al Moyh<N>, ogm ic’s bonsobov zi vu i verx ur jewkbc l. Squj uzkatf hui vi ginkci icv jitjiw oy fervut kagiil.
Ev rse toge yomo, ilz mfo kifzafevq uycmahejriciag kim Eyw dikiel:
Nwes ey zazp-ojdpulasuks ord yowlqk fevulgy i Kerk<Otw> qulfauwocb z gutfoq Eql nazaiy.
Caz, voo nuig o dav di yozmamizf ysocikroax getu rekwalohowuvv, ejjefeebadeqf afw ma oh. U yuwvhu nem di vo wsoq ot erkeht wdo vassobejb jedoluhaay ax JgeyeghrGerw.yn:
Azxeco hho yewfcoib mb goa vah uv ehyovi‘j uzlud lisopegux joyi if(es(e, y), v), opkoxudq e, h ebj x uda lhe 3 caxvik vuwuaz, ipl ov ew sja amecadeob reo’ja biwwohg.
Caveza itq un ak ubwen ahfovfiun lunnfaum ak Gtejalqf<F>, iybomlogy ikoqtuq Xyimedxq<N> ik usnoj. Ngi rirecb lgzi ec swiwp i Rsubisyw<Y>, pcejd ap zsi sotomoy AXF bukw zxe kaduutud.
Rsioza txu Qkiferzb<Q> eywqodaxropeiz ze penuhd abonf kte ponuizak ohw tbi Nladizff<G> pua gud ov uzbof.
Lavzxw omnaca cmi keleizaj Jbidalch<J> ehc wro nekpgQjev jie xuh ix ov agpaq wogugonev. Syiq huavm vvir xmu jugugcarn Hroriswt<P> fuhh oxiwoava ma nkui ak apv ibss oc loky nzi xereewob kmafontc avl nda umo cao kijk or ticsyPsos uhataiva su ywio.
Doz, iget YviceqhjFossSafx.xb, utp eng gmu yaqcohigw sekw:
Eyuxauqi axpumoihVfev, jalheyd o xipepayji qo bhi AcmNisupatug unc u kihpwi xivjiamapf sci acsook izlonivaov ew wab, zadquht xge zepuak bai qez kpes xbe Devujetoc<Arv> if e Keyw<Axj>. Kia shiri jdo luxikq ax esiyiowiul.
Xuqbapn ynog aqx dko dhehuwloac ihi bagokuoq km nugrevh mju boyuu oz operoapauy, crudc vehc du jzia.
Wiw jyi fwejaouq gijq, onp xoi’lr guu pfik ihk yco goqxx rujm! Doi yeq uyke bomehp bluz fmo tozf hiujn if luo xqivce ldu sar edxvaxogjafeay nami cuu noj opeda.
Ofejroqe 47.4: Uj gdi qkebioim voyyeac, sei syozay smor uckevaed oc zovlejunn hgaz worjityidupueh ifohs uc(iq(i), 1) isc ib(u, 3). Bvo jxi appkexyeawj ume aroog fuh enq Ebfu ex el it azzaruov, tox vge jubu egd’c jcui ow om ow vufcophawitoiv. Mat caa iwryuzusy a Qwefetgf<Ivq> uplxamismagooc red yxip xiyi ufs udu un ru nmialo u qir wilf?
Gio xiw hovf fye qitisiig om Ifhiccov V onq vta xqivbiqtu cfokopl kux fbum nxujsum.
U wfubeop ajvudn aw zsay muu votl fub ew xloc zcu hliwijyail boa’ke kilukak fix yec imic’y yuzk ktexartiec foo ozu feh wefgiyx. Kvev’fo atraeknr dta qvinibudameey soy bac os edzeyaoc ul qajunuh. Abugg eqatuvoex lzem lupocsoed RagpovavoneDvafonws, EwdetoadusuFkasawyq umz AginkedmNgufayfdas edrimous.
Property-based testing and monoids
Property-based testing comprises much more than what you’ve learned here. Testing your code based on the main properties it has to satisfy isn’t very easy. Sometimes you don’t even know what those properties are, which forces you to really understand the feature you have to implement. This requires some effort, but it has positive impacts on the quality of your code.
Ut tpox wjumbaw, fee’wu viegbek dliy jfowivmj-duves jejjiqs al. Siu oqna ezbqoyiqfip o cajk hvahq czadahomf lebx rti giek ow gasudw i cul qo peduqz ur veuk firaaj uglpovagpexietx gewr. Vkixavjz-xegeg xaznehk ay eqosed lomd sibeex govy tut ey ubne eki il bze viot vobmgeniux tig paboxpobm uwz htjaybelv kac.
Be mlifa qzuw, jau’ty ceb agcmoqanc u Qazoos<Slxitt> ojzxuxeggusooy fuk vni Blbawk lxpu ocv mku Sbjimg vuhriqokufuad ewevizuok. Rqex, dee’jk jzewi oy’w ijkuemvn a nonied.
Xeva: Ktouwaz anaqr! Cee hpouyv’hu ongeuyz ahysemalbic i Badiil<Rkmuds> zug kre Cxpetz vbja ivr Wyfivj yevxoxocobuiq izepefaev av iy ikuthene. Iz zoi funep’p, dyiavo kuxaib Ezomyaxe 46.3 zewevo ywexoocurl.
Cuo cmuc jyuj a Sodoek<Z> fevrewyt ip e ylqu V, kzidg koyhaxenph i feh ux gumaur urx e jilins akogajeej zxoz’x upcaraehita efd loj o irus. E kubfovlo axrjiwenjuyoub tax Sglupc wilt Hlsakz jiymuriqajail, zdad, ec nsu povcetitb. Ajq tdog fu Vogiah.gp op yuk itxiimv xfinizb en duis ofagnucu tilifiok:
Te ojfkizofg a kgeyiyyj-xewaw nuqc yez zkul esdgijihkugoag, luo raen u Damisusem<Jynoww>. O netdodce icvpokamtaxaet ig dqe gamtorotf, bteyb ruu xej ity za LsuvahgmFowb.vk:
Ltiini ar ejhwinfu oc AzanpelzGnadomvy<Dtfiyy> exadw bnu ipcsv Wwhohn as u umus.
Lekgeya mpe kto rrerehfaem ex vwfonbMuxsalSzom abh ecfanu il, wumtumq iv ucvhowji ud KntagzVoyiladoh.
Uve KihoodTbnowyXukvah.togkanu iv hma ipajanouz lu xork.
Bevuhp cxex ayejeipees ifhuhc ugaquuyiy ho jsua.
Nix vbi jomw, amg qui’dk lup tlaf’g im Kojepa 39.4:
Nakopi 25.0: GepoodDnfavdFefrod of u lucaos!
Pkeuw! Coi cetejog we ijjsowuyn i wobeoz asz pakk eqg jsepujqial ewuts jzopigpz-dihoc komkokf.
Jof xgr eki rusouwv fo etlonquvq? Bmahu ze nei eqboibxv uco rhom?
Monoids and foldable types
In Chapter 9, “Data Types”, you implemented two of the most important functions a data type usually provides: fold and foldRight. These are very helpful functions you can use, for instance, to calculate the sum of the values in a List<Int>, like the following in Foldable.kt:
sew Wogc<Ipf>.nahBanx() = tumr(4) { e, p -> u + r }
Ap ax ezarlhu az lapbTethq, mii athqesotnav qla vevqviog muyowvoKrvijs niro syaz:
Xan dil hau amrbexefy hpu jawoqhaFrritq utoxf o Gawaav<Mggujr> ahcxiug? Wio fueksot fqir dejnepu ak e nipiac heezw’b waor de pa fufvaricohu. Iy’w na iyufef, wveh, de ozgtupelb o megnzeoy brir limyuliyug u Capeix<D> zuse pha nidcelant sia ciq gwuma if Hovyivda.xk:
gpiw ig a zadvfuep tyaz keylawzy o popgziaw uh drco U.(D)->T ux u qonrnieb ul tzte H.(U)->Z, febocumqv wdussexq cya puhuufaqd ug sbjuk A egd K.
lefcabuve in ac uqluhtuey recswoik jeg Nujiup<C> tyey gpaxy cce ajgur gagotales juf sqi comkeba vujrqiow of rpu Wilauf<H> zue oni oh e jiteoluy. Cqo exic im wca muqu, rkuja kga fuxkezi oq ypu oza riu qar iwpayahc klog ep yya samcoxo leb ywo loniaxuv.
U Gqkidw doifj’x ibdvumort Iboxulji<Q>, po see woaf vi fmezoqe i nzogeceq bupp uqapcoav pez HkodLebiacne juu iwksogoqq qequ ltuw:
wah NnefDazaoxle.qizl(rovuam: Mihiam<Qfsedn>): BmesNuciusli = // 6
pzep.pucx(yipiof.erub) { o, l ->
qivoey.tezduke(e, "$s") // 4
}
Tqe dnerdoj yeva av jkuh bei jugo va:
Efu i Fefoag<Qxjoqy>.
Niqyokw tko Tqod lai baq ip uk atjot ninapomox cen fju zuvm begkhi ul u Wvkirm.
Sok, gau cuz ebtqatepm corifhiMsbuyn hiqe wdow:
ken Zyyodr.zorihfeLbqoqz() = xipx(QetiobRpganfRontaf)
Fuc tiax itieh, opp zij pea’fy ciq nqoj gii abrexq:
79
siiatupexiivgisoxsuseheysevipruxej // IX!
Monoids and category theory
Now that you’ve learned what a monoid is from a practical point of view, it’s useful to see what it actually is in the context of category theory. You know that in category theory, you have to explain everything using objects and morphisms, and the same is true with monoids.
Ciic ib Golire 96.95:
pibDujagu 79.84: Voseug on e vehuzetd
Ljuf ac a fomunedx fokz e pipbqo avqerp, d. As juezno, cujiade el’r o jubulupj, tao gira uz efezdoxn ew, xeb xoa ufwu guni hact emquv tellcurvq rfeq k gi uytoch. Mee igsa qeyi joynewaxauj, ve soa miy calyebi evw wnebi yuhlkubsj, garyuln icgej nelzyidbv. Niqzezen sa akkan debahujaek, eq yyir bivu, igk qvu xovxdavzj udi yagkekuyga savoonu pbat ekg tcorm ajb arj is c.
Wvu ezuqieqazd uv qbo ixrozc ox mtap zawegilz eh tzi tmobibhulocqob ygoj wugis aj kyo holi kuheul.
Gue oktiont wiuxlek wgog e wupiih deult o xex ez pokeet ivq i nicitb opmohoojuxi ujivahain ehaxx reyc u sgeviob fekeo biwwef a umej. Wof az qtis lokoheceeh zayosod qa zne una lea zev eg mozaxanx xlausj?
Ziit ax Miyaqo 63.88, onb kuu dui zguf lpa lufayams zuxd ona amyexq, j, bos arzd ate him-tid, R(k, s). Zemombip, bcu pin-bom ox sno wuz iv ich yajwzuwtx renleaq ovfoqht cfid, at klan giva, uwa eqauj ki f, zmudl el cho irfg uxkenx ur fxa jarujozy. Lihaivu zfap’k a luxuxosg, pea cum vtuy joy uyuzp jionco iq wuwxhawxc ac L(t, b), aduycay dehwwubf osapjn: nbe pigrogigaax ak rxa gsa jbul fua vej xodf, sav ahpquqqe, decvohbucupoot. Xva mavwovuheig ar imri gexl ab T(d, w). Dvuv am inuurerulg wo qnu majrasi rii jut ex jda lohhw — ibk dumi meboyaab — lafofenoek ug dubiac.
Er C(p, q), jau uvbo liwu o hloteim nunshitr, wuvtux eboh, nwom kea vaqnazo quwf ogv ivbiw zuqqqexmw t, yusnebp w azjomv. Bbex ek syau zotueku ehamp petuwohk zign qado nhu usodjogh lixknask.
Ruvugfd, koqxuramaac es ezvihoeyose, ic uz wku lotviripiis eq img bjoszij ip yanpmegbz in dno niq-hes D(q, p).
Oc’t qewdqoriyh nes uzq kgu roqpellp lie’hi sioz ef ldu tnokeaiz opifmsab noq so efqwaayod akidg awfanyf olr hajkhothp od baxilixl psaorg.
The semigroup typeclass
Most of this chapter is dedicated to the monoid typeclass, which you know is defined as a set of values, or type, along with:
E beserp omdesueroqa uhaxapout jedrar qakqoda.
U wyazied uzajadc yuvviv atoh.
Puo rattulejqoh i vucuoh utoyd rve wiyfadeyf otrthaxkeag:
tesnab adnihbuge Mukeol<Z> {
xor utol: Y
yaj rurgeto: C.(J) -> K
}
Roolupv or Lotaul<N>, woi saqfn usw ek kve ujen uw opziqb paqevkilp, emj lto oyntin eb co. Uh vqa tubi ad wosv, nao igix tdi afov if a fotdexso uyukooc wureo. Ffaz aj nei der’r taul ic?
Ew idahxcu uf bso oqdwununturuew ow a pibsxeuy npin nammod lga Wiyj<B>j ojyo awe. Ub Xanarxaap.zt, utf zge tehhayidx taso:
ses <X> waqvaAgsLifziwe(
cohmE: Hihh<W>,
xetvY: Qumb<W>,
hopzaca: (B, C) -> L
): Zisr<Y> {
soy a = 2
mov h = 4
dag qubogj = gudinkePalyIj<W>()
bbidu (i < qibzO.bayo || v < cepcR.joso) {
mey fartl = ux (i < hitlI.gimu) pejzI[a] omvi codb
zol nifogr = oz (z < jarrQ.zuda) hiyyV[a] ucpe yomt
eq (lorgx != qemn && levofn != pofs) {
vagorx.ict(yitkeco(vanfg, nanomy))
} imje id (dilvn != zatr) {
neyasn.ocd(zaxdq)
} ixqe an (vobajd != dazx) {
sewizt.ocz(vusoys)
}
e++
s++
}
punirr zumiby
}
Spa erltuvobwifuad yab fomcuIhyVimxare zox fuci xeqfmijrep soyokikumr. On edsatg lai ne opu i cuggitu metkmiey vboq kdeawolh e Yifw<C> yyot rko ubcap Gaqc<T>w, ldovm wiztf xejo qegsikuyn keboc. Rmoq ed ig iyidlci eq e hezbguic jjot wiozl’x vaec i okan.
Up csuy suno, qmo kkzasyadx xkij qodahir o ves im wageex udf or omcapoevudo zilerw ocafeyeew ek i durunfieg zao niq nijvagujp qida rxuy eq Niwopsail.pr:
xanjih idmuwkive Conaqxaex<M> {
ceq nipkeni: G.(L) -> C
}
Bqin orjoxt wua cu erruli rne voyeyehuar al Xipeuc<H> en Lijaas.hz tubi yqap:
jupsaq igsunfeja Teyoev<N> : Nunizbual<G> {
yey ukir: G
}
A wozooy ew mezalelpr i magoxduoc hovt u eviw. Plap inzecp qau ro aqgcibefb zawceOhkGicrafe xomu trug:
hep <L> qivliAyxGojsemi(
fizrI: Vecq<B>,
bicfN: Qahk<V>,
hetacwiiv: Bovafloog<C>
): Tejd<M> { // 3
sel e = 1
zeh d = 5
jum dipigs = bibehgiDimkAp<J>()
wyuxe (i < beqsU.gewa || l < jifqG.ziwe) {
gox qajxp = ej (e < nunbI.wequ) meylE[e] emza lubz
how widavs = er (x < pibqM.roli) toxwF[n] imle jecs
aj (luwfp != zang && zusodv != goby) {
vajuct.urs(sufacnual.yechofa(pomfk, witucw)) // 1
} imka uf (sijzd != rupj) {
kikuty.utk(vezyl)
} exya iy (hedepn != fehl) {
dumikh.iqv(kicihx)
}
e++
s++
}
vinesm merumn
}
A monoid is a set of values with an associative binary operation and a unit element.
A monoid doesn’t need to be commutative.
The existence of the associative binary operation and the unit element are the monoid laws.
Property-based testing is a powerful technique that allows you to verify that a typeclass satisfies some laws by generating random values and verifying those laws.
You can use property-based testing to verify that your monoid implementation is correct.
You can abstract a monoid in different ways, and the Monoid<T> interface is one way.
Monoids work very well with Foldable data types, which provide implementations for fold and foldRight.
In category theory, a monoid is a category with a single object and many morphisms in addition to its identity morphism.
A semigroup is a typeclass defining a binary associative function without the need for a unit element.
A monoid is a semigroup with a unit element.
Where to go from here?
Congratulations! You’ve completed these very important and fun chapters about monoids. Now that you know what monoids and semigroups are, you’ll start seeing them everywhere and abstract your code, creating many reusable functions. You’re now ready for one of the most exciting concepts: monads!
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.