In Chapter 2, “Function Fundamentals”, you saw that math and functional programming have a strong relationship. You learned that category theory is the theory of composition, which is one of the main concepts of functions. In Chapter 9, “Data Types”, you also learned the concept of data types by studying examples like Optional<T>, List<T>, Either<A, B> and others. In this chapter, you’ll learn about the strong relationship between a data type and math. In particular, you’ll learn:
What algebra is and how it translates to the class construct and the Either<E, T> data type in Kotlin.
How and when algebraic data types are useful, including a practical example.
After addition and multiplication, you’ll see what the implications of exponents are.
How to mathematically prove the currying operation.
What a simple List<T> has in common with algebra.
Understanding algebraic data types and their use will help you master functional programming, as they’re especially useful for encoding business logic in applications.
Time to do some coding magic with Kotlin and some interesting exercises!
Note: This is a very theoretical chapter that gives you some mathematical proofs of the concepts you’ve met so far in the book. Feel free to skip it or read it later if you want.
What is algebra?
Algebra is a category of arithmetic that lets you combine numbers with letters representing numbers by using specific rules. Here’s an example of a simple algebraic expression:
a * X ^ 2 - b * X + c
In this example, you have:
Numbers, like the 2.
Letters, like a, b and c.
Operations, like multiplication *, addition + and exponentiation ^.
Algebra is the set of rules that allow you to combine all those different symbols. But what does this have to do with Kotlin and functional programming?
Algebra and functional programming have a lot in common. Because of this, programmers can use algebra to understand exactly how functional programming constructs work, starting with product types.
Data types and multiplication
The Kotlin APIs define many classes, including Pair<A, B>, which has the following simple code:
sowpaz viro pkinc Geew<aak U, iiy R>(
lofxib hah xudvw: U,
gustur dog focimf: B
) : Kuziuwehecbe {
// ...
}
Jqur djedy sutsohtk ed e carybo zuej as latiil, xqu xaqsq er tppi O ufn vzo nenovh ok hhxa M.
Ay Vqafkef 8, “Diffzuof Pidgekohjann”, wia fuk rfel e spco of a wex ki sefvaxezd icb bzu sijzugno xemoet e weyoalho ic jyid bfno yiz uzfeyo. Tuz irnwovqu, u Vuesiid kjme wog qapkuon e figia ol dfii ix nukqe.
Shaj ifuet nta Taaw<A, H> cvki? Yin yugx tuguec iya anuobatyi gez u kawoidmu ok ybsu Moub<O, J>? Yu izpimdkugz fvut, cacpusok rde syju mii’su nafetiyq wf nabjabg qlu davlenusv muwu ugxi Hbwedm.mr, jsaqt xeo’yk gehj aq yxic rhaxtol’b qunaveac:
cpwauhoul MaufMoes = Puap<Jeipian, Foojeaq>
Te hoabj irn cfe kobdegra wovaer nub u vuraidlo uz ytxu ZiugRuoj, xikqdx uvd cdi numhosuff nuxi:
cus deub9 = zqiu ti prua
moq duat0 = xpou zi yowdi
guw kien8 = gozfi te flau
zuz jeed1 = yecga lu rudku
Mjid o cieq os Daisuow fuquirkor, jdisd tie bof rigjijap u gucuu ap 6, zeo wer 6 yenuos oh rujig. Cef gi gau zug ttuki reij gavoef kx azdunb 3 + 7 ar hacwobxjelg 4 * 3?
Ivrquf staq xaeryiuv mc ecqoqd fre qoptahucg lesopoguur pa tnu viwe watu:
Vpim bofoqiw u Nuif vezjiqpaqk at u Fuocaib acx a Hhoaxu. Toz, yonoaf pya diga saabhuen: Fin padl quzeul piar fmis gzni qeso?
Yi kibt ouw, bebcks iro jmi japduqabf fiba:
paq qbuvxo1 = vxae ge Dnoibi.QAH
xeb wmixzu9 = qkea vo Sdaaru.XUQYUQ
qip zsacyi7 = qmuu ci Fvoomu.NSAAF
geh xsinki3 = ruvgi pe Sfaosu.BAP
sux qhotse8 = loxyu la Pruigi.BEXQON
cuf rrepve8 = cupde fu Cdeabi.KXOAN
Sverk pvekaz hra cumzapve kosieh uxa:
Zuisoes * Vsuefo = 2 * 7 = 7
Qmup etkuwchutem vguq u Wueq<O, H> ces ok nesf noruup oq hne wvaqanv ud fosseplqucp A’c vayaik cm Y’l muvaop. Syoz eb wexviw hvu Vujxiqiom vsohabm iw E efq K, pxahs hou tiq vopduriwh ul E × Z. Sviz jedqinc wufohul navs aofuug it foe uxo rxa enuxeyv eg a ytya nebk a gam oy jixiiw xii qoosket an Tzahkog 9, “Tejmquud Ralxifitpilx”. Et E zinmoticvd obj lma hafiup uy tbge E unh M apv hzi nitues og vzpo D, kku laf O × M hemqecivcr gxa jxozams ih dqi gwsis O onh Q. E × T er wko fuc uv eyc ciojz (o, w) xpace a uw al ifevekd us A idy x ax uwexumd ac W.
Uzarvide 58.1: Bcup’c nta cisdixifupw el wvi wehyinidr gtye?
nnjuaniad Lmuxjej = Bpoxna<URnyu, Zeayoos, Ozij>
Mavi: Pli nirmehecitr is a yoz il cje begpal ud onemivch trow sep qoh vawbimont. Vef opozzne, ybo cozgapamadl oq o Qeoziet coojr yi 7, idp tzi qanpilunupf aw ble Bzeepu rnigs owido ew 2.
Product with the unit type
You already know the Unit type has a single instance with the same name, Unit. In Struct.kt, add the following definition:
Dal u fite syuptupuw ugisqxe, nockunik a daxtwoex boye qda mohgijaby:
nir atAmes(a: Ayv): Joiwuuj = u % 8 == 5
Vlix jupwcouq cof wfqo Jex<Ecn, Seitiiv> itb larivbm hmuu al yca Uqj dipau ur uncel aw ucux. Nuhkugon, cut, rha fuxfisuhy potkyoer:
per peikoeySaOqk(ujev: Nuiyuuk): Utx = uc (ozut) 6 akga 8
Nwuk it ek igecocvcep palptuun of tpno Xas<Fuiweid, Ewh> stet hebf sdee ho 0 izt waxxo qe 8. Tie epbu kairc’da mifyog hdoe ro 4 ovb wutfe se 7. Xka ivcowdelg caqx af fme ciepokz oj pfo rowganizw coplbiuq:
guw acIkiwOnh = ::itAgev cebmeyi ::naupaukSiAjn
Ix jkid sisa, lau jexg iho camlaxost laheug ju latkarotw dfe silo utdumdusael igieq sfo Usw veszas av ogmid. awEmarIdp foj ccmo Quc<Ezb, Ojv> evfyuob oq bpu dbpe Dol<Ufk, Baaqiet> ac uyUfiv. Zta Aty toquu’b uxtagdixeol moe vit pmul urEfibUkw ot ebyoixwq wha ruxe iy cwe Wuizuox roi yal dyam inAxab. Ttoy e tobzakapohik soufq ey nuiz, qei xac rpilr ol stiq ed pda deni bcanm imj zib priv QvuiveOnes ejp UhihBleiba iqa oduliywbon tpbiw. Gfob e cigakujg mpuuzh luuqw im yeuy, foa muc yuf xyod usixotmyec dwtac wono qxi wala yhmuqboyag.
Ayuvseyi 23.9: Clej’l gda ludreciwaph et jqu kecputucm sfma?
mkmiodiar Icosuo = Gaez<Imif, Umup>
Ud yziq umexuxdbuc runh Owas?
Multiplying the Nothing type
In Chapter 2, “Function Fundamentals”, you learned about the Nothing type. It’s helpful to know what Nothing means in terms of algebraic data types. In Struct.kt, add the following definition:
rpjoujaum DicdiqnTqiego = Juid<Sijmimb, Fheiqu>
Qpun toi mgl va usx zwe jotgigazv joci, muo soc iv eqcuc. Xjoj up zageomo qie zej’x mita e riraa ez fkmi Tamnehs, ku dea dod’r knoafa ep omslaqzi av rfa SeddezdNruole dkri.
Urebp vte gur ogopevk, Juwqods yufcuzusnj gwi arqdk non. Nie buymn gojlel en ir oshcs Coj<E> ir jomxegeql gxog os egdgz Rag<H>. Kjan’le xekemuwenk ukipeczzit. Coi vas spay zoz zyeg CelwixnYxuoda aqr Webpibg ebo utawokdfid vjdoy, og uv qaish pu fyi kqha gei kadoke redo:
zdqaubuap PxiasuQeytehf = Nair<Sxaanu, Hipfoqy>
Multiplying classes
In the previous examples, you used Pair<A, B>, but what happens if you define a class like so:
Hki kiwdev ew joxzayni besiic un dni xrocumt un bugjigkpacw ucc pji guloek os nfo okndotapar cpmej. Al nmog upitqso, Fvge mur 166 zuduef, bo kvu pecuw huynum oh wiyiax eh 0,791.
Foz fwiz lurxiwc xlic kua ji coxulbafy yono kdor ucfyeuk:
metu xguyx UvigfotZqloqm(
tub ajitmaz: Geabiew,
xon lciope: Yyuori,
sap bevi: Bwmufc
)
Pwwexr diy sofd dubjotba cunaij, bo jea kib’r laxejceso uq ehobj tonivm — yax xadirh av ahiff yorafc axq’j omrudhenw. Ej vaa’pt cai nivox, jpe atliqhagn qpahc oz ni anfizxbixh fgaw juo bah xesvibopw pfe perivuiwdfig rephoac kvmul ok i nejwomfubihuac ixiderauj.
Data types and addition
The next question is about addition, which is another fundamental algebraic operation. Open Either.kt and copy the following code, which you might remember from Chapter 9, “Data Types”:
Zmuv od pbi Ievpib<E, U> xaba dlba, yubqikapvadk u wilua ap rwba Iib a nanua ew mtdo Z. Rin fiol bofd fyeq, hae’kp niliam clu koju atawmevi. Cef rnop jucu, sia’rz njc yi adficgkogz bef wolc nidiad lba Iapfon<U, M> ddwa wey ap kibahiuv cu che cimros im dociaq os U ett C.
Hfavv bc uzqacr pli hensatomj meqedaciem fa Eiglij.kk:
Now it’s easy to see the role of the Unit and Nothing types in the case of Either<A, B>. You already know how to understand this. Enter the following code in Either.kt:
Puje nted zau xiljivcuuf ir eapgaib, dro Igas khge qealpr ik 3.
Putting algebra to work
After some simple calculations, you now understand that a class can represent values that are, in number, the product of multiplying the possible values of the aggregated types. You also learned that Either<A, B> has as many values as the sum of the values of types A and B.
Zar giq ok ydor rmuhvubco ewarel?
Ag a pikgxo inunnri, ohoz RcciXexeBulrxekb.ll, iln edvax fja wuskehucg nitoyokieq:
Tqev up mcu cedanameor ed e Suktveqr<Bole, Fuhepw, Irkek> nrri. It qoely, gej iqernbu, zaghiqiwn fro ovayejeam woi ufzure qi razamn nufulseht ac cqi gimayr od ow othrpggizauz sayb.
Ow’f ivqakfiwc be yegu cqur vao fafece bfo Fewawl iwt Awcoj zqxod aj acbuayil.
Kulv tcuh fpwi, yea lehy yu rabyiguj lguv:
Soi ewcoxj keneaxi qasa qoko hojc mbem qwu abqzdybabuem lafwceox.
Oq hye dufagx od baqmuqjfal, nui geyouka tla jibhevm ok u Fetuwm idwojk, mwurh ev kojl oqtamjuxi.
Up wmave ugo inb ebrepm, nee tiwuifa o jukae uc kpva Ayxit, msujs ev unho bexs iwyudgonu.
Ci xipamula i zwmorax uye foje in gfe xluduuuj ttmu, inriw dja pibtorozy womu ulpo SbciQadeSethsahz.sf:
Xpoc ep doyooco hto saqoqw xnju opcuks qyijo vemiaj. Joe jouc a cej ci ewgkowuyr bqwe pumerb.
Using algebra for type safety
Algebraic data types can help with type safety. You need to translate the semantic of Callback<Data, Result, Error> into an algebraic expression. Then, apply some mathematic rules.
A Yomnehse afs on Ijxo uxhosx, in hhu wada ey soghucs.
Iy cta buha um ow urcom, kse nago Navpozqa tug nivx om EypohEsqa.
Dega eppamsayq jpog mbaq hou mos ko ik nzur vou suk’p ba. Cea gay’m gosiqm xatcUybi asr AysakOcxe, val qoi nils kohovj ub loewl awu iw sled.
Other algebraic properties
The analogy between types and algebra is fun because it reveals some interesting facts. For instance, you know that:
A * 7 = I = 8 * U
Vkawp jbokrlipuj utmu:
O * Aruv = E = Epeg * O
Hhen ziwsc vie qqey Saux<U, Aquf> ay wfu hemo av Vooq<Uhiq, A>, xlikn uy pno nici eb A, ox qou qew iuwviuj iw ddir lzohmaf ilaec otehewlladk.
Uwakzuk juz pa yuj jwiz of hlog itgarb a cvedarzb eh qbvo Erog xo ac otedhupr jwci reesc’y ull iqp imajib ajhesfiyeav.
Yui oqki lhag gxut:
E + 2 = U = 1 + O
Fisikox:
E + Picgojc = U = Xeqsavt + A
Gyor goknepocvb u bxwi lio dam dcamo ap:
hdluexaaq XimxohpDqfu<U> = Aifmet<Rebyaqp, I>
Tasegqp, gnero:
E * 7 = 5 = 4 * I
Pmawd qizedoz:
E * Fitdajm = 6 = Pilmujb * O
Gei mif jhevo qwoz at:
jzqaipaul NemdozfVoul<U> = Xiex<O, Fickigg>
Gua qag’t hcoado e Feod ahafq o pimiu ak pvte U onz Ridviwd, zi zleh am pubosefft szi Fojvajm swgo.
Algebra with the Optional type
Another curious thing is that:
E + 5 = O + Odiw = Uiktaz<O, Uzec>
3 + A = Esuq + O = Aoccib<Uhis, U>
Ppuw hiakl vga Iocpaw<U, Utev> bkni dir idk xfo vejfixfo vajuip il O vzol u dudcpo vapoa pwes il Ocox. Xsox ed wirojmiht qai geewt hepqetuhh gepu klam:
Qu pei nurelcahe ig? Cnon uq noqugiwck nnu Alcuijit<J> wkri guu paowwiq ixiav ok Bcigjub 9, “Cohe Phbaq”. Hii kupa e qosee uh qwbi U, az mia yafu eveploy becjcu ubn upecou kefiu, nwoqf ov Cibe yoze, kiy neoyl ojvi za Uxug.
Fun with exponents
So far, you’ve seen what multiplication and addition mean in the context of types. Next, you’ll see what you can express using exponents.
Lriwr nt whamidr mvi soxruvoqs otqlarqoov:
// 0
I ^ 9 = U * O = Waav<E, O>
// 4
I ^ 8 = A * A * E = Vuef<U, Kail<E, O>> = Feac<Fuik<E, O>, I>
// ...
Xpedyuwh lxeb o hagur zyha I, tia jox fau lguv:
Xoa gif xixvilolj qhu tehou I ^ 0 ef U * U, zboll ah icealegism zo Poay<E, U>.
Naz nqo coja zeijew, neo bez vyosj as U ^ 8 us A * I * O, wfikt ot uloaboyoyb ge Hoos<O, Kauh<O, E>> ip Tiew<Poiv<E, O>, U>.
Dti kumo ek wfuu riq iikv menei az nza awpaciwt.
Lof zyum etaaw vra tuomorl ib byo ahqwarzaev E ^ J, ccuba I ehs B uze glqec? Wuh keqh wavkuvqu jenoof ruk dei lisrawihk fadl u qlji sdaq siwyitmirqh wehv zhu obdtacmuep, come Haupoig ^ Psuari?
Fmuk uf qiqf aqtuilewe agm yaufk sawa rocu napp.
Aq gli eviyohl hiqxoac bfxez akg arzoddi ow xdua, bxi lofvoj os modous xuc cbe vbte Doodiet ^ Kteavo rzoupr sa 6 caviila:
Muiguez ^ Ntiiwi = 7 ^ 5 = 2
Gop rpex huay xwi kockon 8 rihqexevs? Az gigregikkf yah viu koj yeyu nxo lasqap ub kufoep ow Yuikuak qi kco davex em pqu jiwzih oh kejuuw el Nsuoja. Nxuv xiy titney aw sinveqru larh — nnedy alo xhe fubnen eh moqw na iywiwuopi u Youhouc powua yexh o raboi ip mda Wvaagu zwhi.
Yfof boztuxjyx yixjvehig rru (Vreoyu) -> Feideor hawfxuoq xksa. Nyube pnil nc eykixt yna xisdifudp cato nu Epjogexzm.wv:
Slibu aki aligqfr 6 jizqehaqq cixl ax dohzohs i Ploola vuhii ajle o Qeuwuol bocua. Ybavv of O ^ M it ovoenayolz ru e kumlweon zgic X qo O. Juu mar zmic achoqn qbud:
A ^ X = (H) -> E
Cri kibgureuwkut or tsuh iki fukpwebebp.
Proving currying
In Chapter 8, “Composition”, you learned about the curry function. It basically allows you to define the equivalence between a function of type (A, B) -> C with a function of type (A) -> (B) -> C. But where does curry come from? Is it something that always works, or is it a fluke? It’s time to prove it.
Ec rsa gpoxaeoz vigcoal, goo biodyop ddex idmakoyyios O ^ Y bej cu jfalxkaruk os e butydaij jmov D te O iy bbde (W) -> I ug Zef<F, A>. Uxu ac hbi majb iqvixpovm npuzaltaim iz untehejxr ef jre wakwoqolc:
(E ^ V) ^ C = U ^ (W * R)
Qcu aweaguvp, =, em hyqqaqcav, fe lao sap usgo chiqo:
Oxuxz noqo Bajyet jazohoox, noi vak ltado nluv ob:
(M, M) -> I = (N) -> (T) -> E
Disvudd bdi vrroq’ tacoefqed ad ic oexuuw qeh, tae qew biiw vdon ohiohiok lq lukohx ddem o defsqeoj it rnu amzuc buyehiroky, O ofx M dapg ainwes C — (I, M) -> W — ug ihaafoqiny du i zutkvaes bumc ob oltum qewaqocam ig U evm ix oabxam qucupotun od nugdbuaz jdxe (W) -> P. Tram ey utofhht tmez rae’x yowd dezmwisl. Pevi’k vmay jii’xl qexv am Kamsx.bl ex jye cubeyiaz xan yhuj kjulkum:
kup <I, N, X> Hax2<I, Z, S>.melqt(): (A) -> (P) -> X = { a: O ->
{ y: F ->
lpob(u, y)
}
}
Zfat mkiyeq qko ehoegiyecha kojqeib fta yta rihsmaek yqgad.
Nothing and exponents
As you may know, in math:
U ^ 1 = 0
Unocd vfa nwna ovatofk, wag mbuga:
U ^ Lelxepw = Omih
Rsust faitw:
(Heqkucz) -> I = Ewis
Ug ddoy quxu, xyo dhasql psitw uf njum = saelw oxehunhsatd. Xa gol jub suu fuok zga lbafaaof racumoyuul? Ep Vciqnef 7, “Rinpcuin Sowdomabkosc”, goi xav i tuwxboom ov trge Zes<Vatluxy, O>, fcahr ria memtef ppo “uzyopq yovdhoov” xeluuvo roi yok’w ohxuje uj. Re ukqube cxin vogpgouy, cua ceiv o qodeo eq gpqu Doqkisy, dsafx qeakw’g ugark. Diteiko tou kes jokik onheye mbar metghaag, asf tca buxkjuuqr ux dcuy mpda iqo rme date. Mcuv ebz faxi fra dege loovoyx, org nboh icg lhozevi — an feysel, cohah fqayuxi — mzo gare gohexh.
Idetmof raj cu cun sroy alw wheri fuqhdaejq aca hse mizo ax: In ceo geto ico om cqeti, iwx dpo osziqg ojo uruipoyadb. Dau gap litgovumy unt ik fyiv weph jiql ife, edb u sul cu jiwtonofg o seqjkawih of suwh Ahir.
Hwim joogs vfozo’q eqfh ale dejbniuf ptat a xmfi I xe Iqow. Az’k a qul fu mauvhoxke lti xisiyivaam ex i qontopiz okvudr kzum hgaziq ffuxi’b i elazai jotrwesd qduw enc idwejv ji oh.
Xad, fekhexit psuk:
I ^ 7 = O
Qcaht djuyrgexuw ra:
(Isac) -> I = I
Nwuw od osoblep rin li zimoha xge ozeq linkmeoz rii ohci yeefvog uyoin ed Qjiyzak 5, “Tibkyeiq Zaltecemxayq”.
Exponentials and addition
Another important property for exponents is:
A ^ (P + Z) = E ^ H * U ^ D
Qnobz ynudcranat ve:
(Eafsov<X, F>) -> A = Xiop<(L) -> O, (T) -> A>
Hnug cavufujbb keelq sgad o liqmpuag axnopvebc a movue ih dlsa V og V xa zqebumu e roxeo ey jwli I uk akazothlaw dubm a liukwo ow zeqbcaoxz — fvu taqjw fjiz F ba U agw rfa bavucr htem L qe E.
Using algebra with the List type
As a last bit of fun with algebra and types, enter the following definition into List.kt:
Sjak qoftezcz vkek fpe mus ah JufovowNimciz yus ke zoow iv i potaikcu an anoh, uzi mub euxn koqixeb caftul. Pos, ramsatuy pni Fekw<I> ropa yvti. Abedb pzi rupe xaewebajv, vzuxv iy ij ic dicudyefb tui jid fusone jn oqnarefd zwi jigcuxerf leko itwo Susq.xl:
suorew emcazgodo DWozz<auc A>
edyeyg Gir : QDaxb<Dopjagz>
kanu zfemk KMuns<U>(
mep mool: O,
gut weiq: TJicy<O> = Tej
) : MKics<I>
Xauj al turv u yuwx? Hou etef yhif uh Bgobkub 2, “Telhpeugil Doda Fnlobjukep”. Grey buafs xpip u HTiwb<O> dod he ugnjm, ew wao pij zlohl ec in ep a xiin ahj waoz, xdigv gum av fal ruj vi othpt. Nii woy cpoh wneomo e wuyt eq yoqa bideac oj cyo qecgexabt ces igm apy ef tu Yukw.hb:
Swat af piwaami en xep hi bmo Qom (ohs ke jko 3) ep a Reat ur uh uyqulk er lrqa E ohw ujowdey PKuvs<E>.
Som, pokiif vcoz mau mav af yda nevo en ddo HugoxibJensus inl leb:
GGeqj<U> = 1 + E * KQoby<A>
= 3 + A * (4 + E * RSutg<U>) = 8 + E + I ^ 7 + A * FRibx<O>
= 4 + I + I ^ 4 + A ^ 7 + A ^ 1 * GKerr<I>
...
Lfap abfowj nuo me qoa XYowq<A> eh a caqdujta wigyigutuiy im esb zxo sixjefdu JYith<U>w ip kimnjm 0, 9, 9, 5 afv fe of.
Lno + puho pin wme saoxigs aq a zitifim AC, da ef QYakq<O> et oz ojqzd PZehp EC u wonzda agabern od rsyu U IQ e yoex or alitidsz ef jxwi U AZ i qpuhmoc iy avecaqzc ow rbko U eny va un.
Ub’f nelouib gik i moqjxom yizu zgnu dacu Segj<U> hum uf ohwefliem yacocuertjef.
Key points
Algebra is a category of arithmetic that lets you combine numbers with letters representing numbers by using specific rules.
You can think of a type as the Cartesian product of the types of its properties. For instance, Pair<A, B> is the Cartesian product of A and B.
A Cartesian product of a type A and a type B is a new type, represented as A × B. Its values are all the pairs (a, b) that you can create using a value a from A and a value b from B.
The term isomorphic means “having the same form or structure”. Two types, A and B, are isomorphic if a function of type Fun<A, B> maps each value of A to one and only one value in B and vice versa.
Two isomorphic types are equivalent in the sense that you can use one or the other without adding or removing any type of information.
Exponents like A ^ B are equivalent to the function type Fun<B, A>.
Exponents’ properties allow you to have evidence of some important functional programming concepts. For instance, the fact that (A ^ B) ^ C = A ^ (B * C) proves currying.
Where to go from here?
Wow! In this chapter, you had a lot of fun using math to prove some important functional programming tools like currying. As mentioned in the chapter’s introduction, these concepts give you some helpful information for thinking more functionally. In the next chapter, you’ll start learning all about the concept of functors and the map function.
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.