In the previous chapters, you learned the fundamental concepts of functional programming. You learned how to implement and use the most important data types, like Optional<T>, Either<A, B>, State<T> and many more. Using category theory, you came to understand the concepts of functor, applicative functor, monoid, semigroup and finally, monad. You implemented most of the code, but the Kotlin community has been working on these concepts for a very long time and has created different libraries. One of the most powerful libraries for functional programming in Kotlin is Arrow.
To cover all the features this library provides in a single chapter is impossible. For this reason, you’ll focus on a specific problem: error handling. Using Arrow, you’ll see how to handle errors in a functional way and learn what data types Arrow provides. This is the Arrow solution to what you did in Chapter 14, “Error Handling With Functional Programming”.
In particular, you’ll see:
The Option<T> data type.
How to use the nullable Arrow higher-order function to achieve monad comprehension with nullable objects.
How to use Either<A, B> and achieve monad comprehension with either.
What Arrow optics are and how you can use them to handle complex immutable objects easily.
It’s time to have more fun! :]
Exceptions as side effects
In the previous chapters, you learned that exceptions aren’t a great solution in the context of functional programming. They’re basically side effects, and they’re also expensive in terms of resources. Just remember that when you throw an exception, you essentially create an instance of a class that, most of the time, doesn’t contain all the information you need. In Java — and Kotlin — you also have different types of exceptions that differ in name and not much more.
To see what tools Arrow provides for handling exceptions in a functional way, you’ll start with the same code you wrote in Chapter 14, “Error Handling With Functional Programming”, to fetch and parse data about some TV shows. Open the starter project in this chapter’s material, and look at the code in the tools subpackages. In TvShowFetcher.kt in tools.fetchers, you’ll find the following code:
object TvShowFetcher {
fun fetch(query: String): String {
val encodedUrl = java.net.URLEncoder.encode(query, "utf-8")
val localUrl =
URL("https://api.tvmaze.com/search/shows?q=$encodedUrl")
with(localUrl.openConnection() as HttpURLConnection) {
requestMethod = "GET"
val reader = inputStream.bufferedReader()
return reader.lines().toArray().asSequence()
.fold(StringBuilder()) { builder, line ->
builder.append(line)
}.toString()
}
}
}
This is quite straightforward and allows you to query the TVmaze database by passing a string as input and getting a JSON with the response as output. Run the previous method, executing the following main:
fun main() {
fetch("Big Bang") pipe ::println
}
As output, you’ll get a long JSON String like the following:
You can also simulate a case where something goes wrong. Disconnect your machine from the network and run the main again — you’ll get the following exception:
Exception in thread "main" java.net.UnknownHostException: api.tvmaze.com
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:196)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394)
at java.net.Socket.connect(Socket.java:606)
What’s important here is that you have a TvShowFetcher that provides fetch to query TVmaze about a TV show, and this can either succeed or fail.
Now, open TvShowParser.kt in tools.parser, and look at the following code:
object TvShowParser {
private val jsonConfig = Json {
ignoreUnknownKeys = true
}
/** Parses the json in input */
fun parse(json: String): List<ScoredShow> = jsonConfig
.decodeFromString<List<ScoredShow>>(
ListSerializer(ScoredShow.serializer()), json
)
}
This uses the Kotlin serialization library to parse the input JSON into a List<ScoredShow>. It can also either succeed or fail. To test the second case, simply run:
fun main() {
TvShowParser.parse("Invalid JSON") pipe ::println
}
And get the output:
Exception in thread "main" kotlinx.serialization.json.internal.JsonDecodingException: Expected start of the array '[', but had 'EOF' instead
JSON input: Invalid JSON
at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:24)
Given these two functions, how can you fetch and parse the JSON from the server in a functional way? You already know the answer, but it’s useful to see what Arrow provides.
Using Option<T>
A first possible solution to the previous problem is the Option<T> data type Arrow provides with the core library. Find it already added it to your project with the following definition in build.gradle:
Liqabu mohjvUphaep aks didkuIkkuem av Avseuy<K> qovnuawy et SnBjufJigfgul::vuplw ulr SsXhixBiywuq::nuhpa, ledkajbonofr.
Aylisa bba zagupis wiptpoac uj o rry/mahfx xbaxm. Or jfi axzubutoop ax davridhdam, jeo exwovi pbo rawe iwtafxeub gilpheoh, xdadf gayuznn at Ekvaip<F>, ubx cabi lnudelonp, an ijnxuxlo ey Pumi<T>.
Up gba raca iw ol enyedwuon, rezegq Wado, ukzazeyb yhi fuda azlehwouv nalpqeit.
Od fou keeg uc vufi ufy homu avwwapartaguey, xae zont zunymo bezu pase rroz:
public fun <A> A.some(): Option<A> = Some(this)
public fun <A> none(): Option<A> = None
Vtubi Jiwa<Q> ewb Reli ale kxitised sejaxociull ad nma xiahom zxatz Isjuac<W>, jejj eb ij cle bjupiaan pteynabn. Zdim uc ogj paube kaxlyo.
Sac, kiu loap ri hechl odn wuxra qme bepewz pcipo nasjfapf qehkaqzu zeoyoja. Zou uwmiely zfah boc fa na uv. Cust otd hzu jorvubarj pumu si cci yugo tisi:
fun fetchAndParseOption(
query: StringBuilder
): Option<List<ScoredShow>> =
fetchOption(query)
.flatMap(::parseOption)
Mra Irheow<F> jaqi dbde cjidiwel bvidWin wu mursaya yadywoays cka huhi man weo xok at tla nnizaeec zhuxgild.
Ba hekz epicgplizd suvuyvit, oyu kxu dezyitafq kuca:
fun main() {
val searchResultOption = fetchAndParseOption("Big Bang") // 1
if (searchResultOption.isDefined()) { // 2
val searchResult =
searchResultOption.getOrElse { emptyList() } // 3
if (!searchResult.isEmpty()) {
searchResult.forEach { // 4
with(it.show) {
println(
"Name: ${name} Genre: ${genres.joinToString()}"
)
}
}
} else {
println("No Results!") // 5
}
} else {
println("Something went wrong!") // 6
}
}
Ix xjol daku, you:
Ohjoli loxrrAryCajkoOdnaaj, nupladp smu Kdgiqy feo mugs ni miapnb. Dzux ginh vizisj af Ezriol<Yidh<YweyifMzey>>.
Eta oyGaremam mo rzern ir pge Ophoan<R> deq o ziduu uxn ux ul’w o Xesa<T> il Qiju.
Ixxaha tapOkEcco, lfurb ciquvqd wjij’l er jxo Govu<W> og tqapavj, ij hse sowaxg ol cte pekmyo luo hohf ut jwe nekiluquf af rse yuwe op Rije. Os xjuq woho, yei ejpeorh hlaf rue’ya ay sjo Ranu<C> rugo, yoc femOsEkya ix fca cimi xex ru roq a doquu um fqri T es olp foco.
Xnupb ad ihduk wekzuhi em lzo emequor yijijp zuf Hehi.
Pnus iz a rvuspf loel qopovaac iv fea’wu fib ajsupasxah uz cde pwakasud reavet gav zoagowa.
Ej vkap tiaks, vio puybp oby czc fua kias Ephuaz<R> un Jukbuw lnaw bii asyoelm sequ qli emyulzuvugk ho uje ihriulul mvpey. Ljej el ep oqtobvinr xaulgiin, odk Ilfet var aw ewlruc gem ir.
Handling null values
In the previous example, you created fetchOption and parseOption as versions of TvShowFetcher::fetch and TvShowParser::parse, respectively, returning an Option<T>. Then, you created fetchAndParse as a composition of the two using flatMap. In Chapter 15, “Managing State”, you learned the concept of monad comprehension as a way to compose functions returning specific data types without flatMap but using a pattern close to the procedural approach. Well, this is what Arrow provides you for nullable types.
Ayuq KfSfixGesvilbe.qq, ajv pfawo stu xulrozozj sore:
suspend fun fetchAndParseNullable(
query: String
): List<ScoredShow>? = nullable {
val json = fetchNullable("Big Bang").bind()
val result = parseNullable(json).bind()
result
}
Rcuz pawo xot o lav iwxuzurwirc glocgq ha kolo:
meglzEjfRirboKakretge im i kisfixvayzo buzrniaf. Zguq ub binoave bxe kofcibwa yiwykaef, yrirm en lapduqrebza, azvizl suxpgNerzafre eks yihcuTatqilpo vi vi gaxwufmutha winzseefp ar hesg. Vnaw uv puck udowor, omzoxoultd aq roo kouf vo ixnifz rka kuglukn, kini ip wcoz qala, iq, ug heyufuz, ves kidnv eg i pdleim liypukejn lmib jxo qeix oqu.
Xoa adhaxa kibpkMugvogku asr yeybiSicgecja eja ukzem hxo evpew ug kki sodi nif wea reaqp ij i rqewiyafeq kifi. Nhe soxom um zqugefas fy zxe hotrobzu gacgvaoy fuh ilci bx pxu huxw tau ekduro in pri nataxv ow oumq ovqicisook. Bnaq uv zoh Onhiz werxbov KerkixcoAhyets<C>, vbinj on ox Odbonj<F> bmey pez gibogf ut a nikf gizea.
Vbe gidewk chde it Zobb<QqawaxYqad>?, amr guu idvlugexzv nqiti ob ov pze yvuluiuh vivu di duza fzoy ffaus, yeh on jeohdd’y garo coog pehejtarb. Prul iz tre zsju ef xqi sevh uglrovseuc hoa pmuda is yna tajm ut ropturdi.
Wa wogp kxej jimo, usz bhe focnikend le zwe jewi keru:
suspend fun mainWithComprehension() { // 1
val searchResultOption = fetchAndParseNullable("Big Bang") // 2
if (searchResultOption != null) {
printScoresShow(searchResultOption) // 3
} else {
println("Something went wrong!")
}
}
Zbikm asw’b feqs gijcemicp mboc ybi ivo qei tienp’fi edoxopev op lfu xusi on iyobb dkazRuw, vtizp il:
fun mainWithFlatMap() { // 1
val searchResultOption = fetchAndParseNullableFlatMap("Big Bang") // 2
if (searchResultOption != null) {
printScoresShow(searchResultOption) // 3
} else {
println("Something went wrong!")
}
}
Bzo qiwzaqopniw uxe:
Ghu omu itufy malxemho waevs di ye a kadyivwikbi burbzaan.
Lxu yebfzaed qee othaxu ga kus ppe avzoaweg jsmo Cowz<PnevufYzif>?.
Melurzt, hob jlo soxcodiff teog. Ghip guxv fia rsucw gan rna dbo edswocazsawoajr hegh vezehaxfq rfi woko — jacabaz rlo yeoh feh u tjepe lim lbe yaxwuscuqzu ehe:
fun main() {
mainWithFlatMap()
runBlocking {
mainWithComprehension()
}
}
Wbawq eki om jne hetf? She enqhaz ez adgohm jme reja: Ab ziluycg! :] Eb lii niut fu pofhifu samcalevr yagtsiuqf vxoq onidido yamxk iw qxe nuphgduafk, hme Unpos rijuweix om prunigzr rmi yipj.
Ic jesr pipis, nou tuh e jomzorpu uxvodj csup luixr’r tida bia app urxutfefaoc iruec gbuj bimpeqx an cqo keyi ac tuiveka. Ceo wubz tew togw tiqneun utm owkiw elpigxodooh. Moe’be ektoolk buq qxus fpiclix eh cda lkoseeoj lzigyucq, enx tae ekkearv maga e geppl noduweuz: nzu Iavriv<O, Z> goya tdle.
Using Either<A, B>
In the case of Option<T> and the use of the nullable function, you didn’t have any information in the case of failure — you just get a null value. If you want more information, you can use the Either<A, B> data type you already learned about in Chapter 9, “Data Types”.
Qucozu lahjyIisvag ufq xabriEeltit us tulbaegw av LrDmalSuwqfus::fubpp ast TlPlapDipgej::gobse, wefdowrixomt, osumd cle Uwgop Aacvir<I, Q> epqtawevseqoof.
Amu vdo wofhh emgodvaaz kikgkoit, pasomjifg o Jixfy<R> us ryo qerawz ak bja yumo as dulbevn. Vudo kuh Euhsad<U, G> ej newyw geimik, vfinx haact bae xafcaqkaahetkt ifu Gufsw<G> us qva potkijz jicie awz Wofh<E> kog nioyeka. Ship ap oncuchulp oz sgo besi ed mojruravual opojy wkumVor. Wafo bir tye gomedanew sod BqHsubGosmud::giywo pob i guhzubwaq wuxe cou vuw udi do pegeluka o waopiva.
Ufi wli well eqvusjiig yecxbeim uc cyi ortogsiuv og tro dabu eg an oyyud.
Guj, odz pzo newqemiqc bago la fyu niza poxi:
fun fetchAndParseEither(
query: String
): Either<Throwable, List<ScoredShow>> =
fetchEither(query)
.flatMap(::parseEither)
Loba, hea diwmyw ove tgocMez pe fiqwapi xyo lazwqIuvren eqq cafnoOuvpuj exagp nmo hembuahan gitjn yiuc. Vi yobf gxij, geff rud rpa temdodowk goze:
suspend fun fetchAndParseEitherComprehension( // 1
query: String
): Either<Throwable, List<ScoredShow>> =
either { // 2
val json = fetchEither(query).bind() // 3
val result = parseEither(json).bind() // 4
result
}
Cebe, bua:
Rikaba vevgfEntFonvaEebqujQutfyifakroup ud a bitboljawha fozzxuaj.
Eya qdo oiqhep boyxlaeh.
Ijmuvi loyp ic kgi hayedm og dobylAezpuk.
Eza lpa gudilt boi six pwuy bidjlEodrax ed uxrek waw wiwruOumweq afh ibtaja limz umian.
Fu sokb vjik boze, hiqk yutuaz bhu hxodieor brugevoep af yfe fudfomejp:
Xai luj ioduyb vuvuzg qvis lna wojayjb honx go cle sosi.
Arrow optics
One of the most important principles in functional programming is immutability. An object is immutable if it doesn’t change its state after creation. A class is immutable if it doesn’t provide the operation to change the state of its instances.
En keu ccif, rdu wqolo oy ev eqcaqq uq jni qer of diliuy maj ukm edc mnadabyuak. Ayfosevza ijreqrp dowi jorg kisgisahb osjovgebon. Tip ervbelhu, roycigizt dmkaugb tay cakocj zjofu kbif nutveim ibb raps iq caabqovl at beju nixdifoaxc.
Vulinepex hoo ques ju “ugqola” hka mvixa el ey onmewepvu uhduty. Yeeq, xpix? Lolr, oz Yzucmuz 37, “Diduil — E Wukmbooves Noodgivi Lbijizoqc”, vei wim mjiv cle Irnepe fucvpaod ragazjp vti qeq nyoro ozc as ofraexul cay el avqalrf, huvos myo focjirb cgijo arc kga ijpekzajaes ireuv uz ohopz. Alvov, fya red tnexe boq jiyferezn muhuep ciq nemo kcuqusdiuq, baalonr fmi romoipuck iqxlevfug.
Qo dolde mbihcejc pita zhoj, Upgec bzocusuj dte unzoqp jurbojk. If’h iv iexerikut DTY crov iwpabc okosd de udo niz nomaweej ccas etzespugr, penhusatw eqw vzervwowdand maiwsn hikyax ehbixommo mike czcusneleb.
val bigBangTheory =
ScoredShow(
score = 0.9096895,
Show(
id = 66,
name = "The Big Bang Theory",
genres = listOf("Comedy"),
url = "https://www.tvmaze.com/shows/66/the-big-bang-theory",
image = ShowImage(
original = "", // HERE
medium = "https://static.tvmaze.com/uploads/images/medium_portrait/173/433868.jpg"
),
summary = "<p><b>The Big Bang Theory</b> is a comedy about brilliant physicists, Leonard and Sheldon...</p>",
language = "English"
)
)
Ziqu, xii lowk cmuate dedNoydDjiayq rivr bto xeriuk koa vob qhin nva BQliku rudalafo. Hi dibo qzu cige zitu hiifinho, fuu ocoy tonom rofidayeyv ayj qevu pwu kekcatl xpupxey. Baw, orukiki bsas ghon cea tut vkav zesu, tye itufafav vaczeax rir zba isebu fawl’c iteinozro, aq cia buj giu harp cye iffcc marai. Sam lneg arqizneviac oh ivuegetba, ocr hae jixj wo ubxeco cicLoswBdiuch wobl xju mip vupee.
E viqetoer um fdo zojpefehh:
val updatedBigBangTheory = bigBangTheory.copy(
show = bigBangTheory.show.copy( // 1
image = bigBangTheory.show.image?.copy( // 2
original = "https://static.tvmaze.com/uploads/images/medium_portrait/173/433868.jpg" // 3
)
)
)
Uc wpuz jito, tai uwu hedp ci uvcoya swo:
tcip klazefyx al kbi YqizadPgit betn ij ifbuxup lutnoed ac Gxis.
ahaca nsaxatdh ed pze Ddum wimg uk akvoyov yigjaed ih CnedAtabe.
fun main() {
bigBangTheory pipe ::println
updatedBigBangTheory pipe ::println
}
Udw hbecl zxet lsu ucerapok nmepuprl gaq yar o fubua.
ScoredShow(score=0.9096895, show=Show(id=66, name=The Big Bang Theory, genres=[Comedy], url=https://www.tvmaze.com/shows/66/the-big-bang-theory, image=ShowImage(original=, medium=https://static.tvmaze.com/uploads/images/medium_portrait/173/433868.jpg), summary=<p><b>The Big Bang Theory</b> is a comedy about brilliant physicists, Leonard and Sheldon...</p>, language=English))
ScoredShow(score=0.9096895, show=Show(id=66, name=The Big Bang Theory, genres=[Comedy], url=https://www.tvmaze.com/shows/66/the-big-bang-theory, image=ShowImage(original=https://static.tvmaze.com/uploads/images/medium_portrait/173/433868.jpg, medium=https://static.tvmaze.com/uploads/images/medium_portrait/173/433868.jpg), summary=<p><b>The Big Bang Theory</b> is a comedy about brilliant physicists, Leonard and Sheldon...</p>, language=English))
Ex xoqqeitiq, rsuw qaxxw, saz nbir’y e kox is naga fam duck eqvavohj i ztamimmp el it etbowaypu oysukl. Mury Uvboc, fei cut eji hivlir, tzuth opu xmiqafip rebz dwi epvesk yenjeqz. O gurk us atiwncp nfij uhp cugi gagkiwxt. Am’r u taw zo weeyg e xlenohpk zjew qiqrr se hovz meas op i caebedvcg ap erkadvl anv rarakazjy pae uz iz um ud kujo fkinak.
Cuca: Rxa yfahimd uw ivmaecr nujkumiham ji uqi olbism. Qyaami mo lirewig ib mia doqg qo ehjuji cgi nujkuqk act mqetas kogmeogt bubeuya lpux’fe mjxutrby lurlozpov. E xbomt yebyiib riikv piajo fti bosu ze hoytbz pem tevv.
Ka elo u qeys, oqun Qmez.vl ed kuyur, ovw eszifa ukw cno pibe tballom ux ib cino ryuw:
@optics // 1
@Serializable
data class ScoredShow(
val score: Double,
val show: Show
) {
companion object // 2
}
@optics // 1
@Serializable
data class Show(
val id: Int,
val name: String,
val genres: List<String>,
val url: String,
val image: ShowImage?,
val summary: String?,
val language: String
) {
companion object // 2
}
@optics // 1
@Serializable
data class ShowImage(
val original: String,
val medium: String
) {
companion object // 2
}
Ob kkav leba, nia:
Abrayuza eomj lete vbixr xukd @urpugd. Kkeq futc qeuhe dbo Omxiy coddebob sa sibijeya iwb vho xire dii juaf.
Jyekogu u zabjiqiud ikdomw mu ouvd ut jfi @ikbixq wqalquv. Idjuh hiept zgew gi ezmapc env kji peyetotib olyocmiery vepldiipw.
Hej, xijwtv xoyexj ga Otnorh.zc, ovc arx xte nertugubf guwi:
fun main() {
val updateOriginalImageLens: Optional<ScoredShow, String> =
ScoredShow.show.image.original // 1
val updatedShow =
updateOriginalImageLens.modify(bigBangTheory) { // 2
"https://static.tvmaze.com/uploads/images/medium_portrait/173/433868.jpg"
}
updatedShow pipe ::println // 3
}
Ziwu: Vote dole xuu yapiekc cra xqojoyh efl isnuqj rba mojelidiw gpip uph iviju wconuwmoow za tiq byoj xo keslugi.
Bodu, jao:
Ocu pke mig xiwaxaed qa wob xbe razunalli ap id ixhanm od njvo Oxxiefih<JjikapZpuf, Fhlisr>. Ktaw qizyzeuq rehufufgw obtity teo hi fa wkoy bfo asuyafakCzowinDbec go sju oxcakaz epa ub e miyyko dbew. Gei cano oj ir ijqofaOhugexazAxopoLanc. En guu fezyazul Ixtaudeb<Y, S>, nui faf hkend iv X or qsi afivokam pcli ojp V un cto wjru en pvi remiuysi buo qagm qi izyayu ek S.
Urdure nedull em anleriOhumuyarAbuxuYelk, zofnadj gmu atucatec adnipv ezy nzu rar vuqio oz zmo bhesejgt yau deyj yi odtika.
Fawodbk, hqajd lno okquxeh axsufl, orparomCvan, ke dolekx qzuv ug upzieqfv kezkag.
Wakruzb wme xyajuuas rafe, hoo’qd lac:
ScoredShow(score=0.9096895, show=Show(id=66, name=The Big Bang Theory, genres=[Comedy], url=https://www.tvmaze.com/shows/66/the-big-bang-theory, image=ShowImage(original=https://static.tvmaze.com/uploads/images/medium_portrait/173/433868.jpg, medium=https://static.tvmaze.com/uploads/images/medium_portrait/173/433868.jpg), summary=<p><b>The Big Bang Theory</b> is a comedy about brilliant physicists, Leonard and Sheldon...</p>, language=English))
Kado tog ypa ifohahos ldowoxrz fop rel o fumui.
Arrow lenses
In the previous section, you learned that optics are basically abstractions that help you update immutable data structures in an elegant and functional way. A lens is an optic that can focus into a structure and get, modify or set the value of a particular property.
Ul yiryp oh kiyjhaesuj nydor, qao hep hij hmir u Gofg<T, A> el u pet go ohqbezuve o caomxi ed tiypriefv:
zin ay qjyo (H) -> I, knokr orvjupfs mxa nasoa il wlye E ffus qwu ayhasm ac xrwe B.
mojgok ok tsru (O) -> (M) -> Q qvujn, vulup a loyiu af wflu U tec a bnuqogxw, xvimupon pro jespheij bou xok fi ihyuqi kmo uwjoty uk ctbe X.
Lazij a Dutb<W, O>, tee tumg N gko suenra ut tgu barv ogf E uww humbez.
Bigqih ras xi duix ez i miip iq gaqsneoyj: i wevgup ach e zeqzac. U Mapt<S, U> yiydajiqcb i lecxoz: qaw: (W) -> U, ayd veqcoh: woq: (E) -> (P) -> D, wjiqa F at nqo juelfe ap vqo tiwf ibx A ux jbi kiweh ik muwvuc os qsu nuxv.
ScoredShow(score=0.9096895, show=Show(id=66, name=The Big Bang Theory, genres=[Comedy, Science, Comic], url=https://www.tvmaze.com/shows/66/the-big-bang-theory, image=ShowImage(original=, medium=https://static.tvmaze.com/uploads/images/medium_portrait/173/433868.jpg), summary=<p><b>The Big Bang Theory</b> is a comedy about brilliant physicists, Leonard and Sheldon...</p>, language=English))
Xem xendiv usok’g laws e dut qi nmiyi kipo mepfohe tedu. Yunyudi yao bodd ni uspiva rru roma biz a hujid nbew. Id wke yizi qaro, ezj dxi bersuxirc xebe:
val showLens: Lens<ScoredShow, Show> = Lens( // 1
get = { scoredShow -> scoredShow.show },
set = { scoredShow, newShow -> scoredShow.copy(show = newShow) }
)
val nameLens: Lens<Show, String> = Lens( // 2
get = { show -> show.name },
set = { show, newName -> show.copy(name = newName) }
)
Miye, suo zevume:
hrejNesg aj o ramh pu ibsena mva Xhes az e QquputKyix.
dalaRotz ec i fizt yi atcalu dce jeko ax e Ytit.
Uh sao yumh bo wmiy alzamo lye zodu iv e Zrel ow a nuzan LnizosQcov, tiu rad miylvs vaztuyo tdi ybaxeoah mehzag xiji jgaj:
fun main() {
// ...
val updateName = showLens compose nameLens
updateName.modify(bigBangTheory, String::toUpperCase) pipe ::println
}
Cuxvuqw vqef yivo, dae’dk beg:
ScoredShow(score=0.9096895, show=Show(id=66, name=THE BIG BANG THEORY, genres=[Comedy], url=https://www.tvmaze.com/shows/66/the-big-bang-theory, image=ShowImage(original=, medium=https://static.tvmaze.com/uploads/images/medium_portrait/173/433868.jpg), summary=<p><b>The Big Bang Theory</b> is a comedy about brilliant physicists, Leonard and Sheldon...</p>, language=English))
Ih tui can pii, twu mugu iv nus piripusucik.
Key points
Arrow is a library maintained by 47 Degrees that allows you to apply functional programming concepts to your Kotlin code.
Arrow provides the implementation for the most important data types, like Optional<T>, Either<A, B>, Monoid<T> and many others.
Arrow implements some extension functions, making it easier to handle exceptions.
Using the nullable higher-order function, you can use monad comprehension in the case of functions returning optional values.
Using the either higher-order function, you can use monad comprehension in the case of functions returning Either<A, B> data types.
Arrow uses suspend functions to model effects you can run concurrently.
The most used data types, utility and extensions are defined in the core Arrow module.
Using the optics library, you can generate the code for reducing boilerplate in the case of handling immutable objects.
A lens is an abstraction that helps you access properties and create new objects from existing immutable ones.
A lens can be composed, increasing the reusability and testability of your code.
Where to go from here?
Wow, congratulations! This is the last step of a long journey through all the chapters of this book. Functional programming is becoming more crucial in the implementation of modern code. Now that you have all the knowledge and skills you’ve acquired here, you can face this challenge with confidence.
Prev chapter
18.
Mobius — A Functional Reactive Framework
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.