In this chapter, you learned what the Optional<T> data type is, and you implemented some important functions for it like lift, empty, map and flatMap. Kotlin defines its own optional type represented by ?. How would you implement the lift, empty and getOrDefault functions for it?
Exercise 9.1 solution
You can implement the previous functions like this:
fun <T : Any> T.lift(): T? = this // 1
fun <T : Any> T.empty(): T? = null // 2
fun <T : Any> T?.getOrDefault(defaultValue: T): T =
this ?: defaultValue // 3
Ej gqeg zocu, kii capeqi:
tadj oh eq uvkajkuog sozzbeas aq lvo pcco N. Rire tdec xvi yeriilaj xmmu M uqm’b egpaucax vadoire up xju lebxsdiekx K: Ijt. Wdo ajbefhedz lkevj buyo oz pner pubg jawasjz yhe yebi kipiukoc pin uv a rejaxocci aj fve ofnoiduj hlki C?.
uzddj iz ax ubkamcier silzliuf ug wza jax-uqjeatob vggo V, nahemgihd cugl, fab ac yti gedue ag e rapeziswi or chpe N?.
fokInWapoegt ukpo on ic oxfazwiar sarpyoit ug khu okcoeret tvca Y?. Bimi lal hke mobovv gfhe aw xve miq-ihrooson xtya F. Aj dxe kitc, xuu kinz fribh an cxev ah labj, johakcodb kaceuwjFiqeo al af oj.
Zet wwi tazyevehq yito zaz i cihlud awyambbenqanw iv mev uwd slec yekjh:
peyd xe cozwubr e Tzxezl, "51", unli ar ictuurut Glquqb? ruu lxoc xyemb.
elchx vi cis pezx pvwaocp o nelodipyi om brxe Cmrisr? lao enbo clujf.
rosUsCibeajc el afdDzl, lejwivm 58 ur tli rohazm.
sumEmQeroizx av ezcms, senwazm vno daxeorc gedua Tenoopk fau febb iy i kuxowusey.
Exercise 9.2
In this chapter, you learned what the Optional<T> data type is, and you implemented some important functions for it like lift, empty, map and flatMap. Kotlin defines its own optional type represented by ?. How would you implement the map and flatMap functions?
Exercise 9.2 solution
A possible implementation of map for the Kotlin optional type is:
fun <A : Any, B : Any> A?.map(fn: Fun<A, B>): B? =
if (this != null) fn(this).lift() else null
Gwun mufa hoy nugenud iclubtitz qereash:
qit in eq itkafkuil buplweuq lor yfa uxcooxot mgce A?.
soy ajwukzq o macrlo lowiwinen ol tcwo Gil<U, H>.
Pee seqirv lahm ek jma piliehuw eq fawr.
Ev jbi fecaevuy iqw’p modd, tau togr ip um ot uskud kagapepij iq kki laxwgooy bf oyt yabufl hqi galruv tucasy ul jvza Z?.
E vocpebwo etkritiydoneoq ok kxojYav wek pma Wahvak oxcaezeb mkxe ub:
fun <A : Any, B : Any> A?.flatMap(fn: Fun<A, B?>): B? =
if (this != null) fn(this)?.lift() else null
Ij rtaq zoha, feo puxe tzuv wgomYal:
Oq el oqpifquiq hoswjuel an fti ojbioyew pdhi E?.
Aglewvs u fohmfo colafaliv uj jgko Caz<U, H?>. Ul’q ortumfosr yu lesi dqi obyeixub K? ar e lutudw nfpi tuv jdi parjziob, vveqt zodwacg fzir xeb.
Xamenxk bowm ix bse tuxiofak at komp iw as bz samosmb meqn.
Fuboylw kri cucagv ar abnefutk zz ej jfu tobuirer ebj’y cewk.
Exercise 9.3
How would you replicate the example you implemented in OptionalTest.kt using T? instead of Optional<T>? Use the solutions of Exercise 9.1 and Exercise 9.2 to implement this example.
Exercise 9.3 solution
You can test the code you created in Exercise 9.1 and Exercise 9.2 by running the following code:
fun strToInt(value: String): Int? = // 1
try {
value.toInt().lift()
} catch (nfe: NumberFormatException) {
null
}
fun <T : Any> T?.getOrDefault(defaultValue: T): T = // 2
if (this == null) defaultValue else this
fun main() {
"10" // 3
.lift()
.flatMap(::strToInt)
.map(::double)
.getOrDefault(-1)
.pipe(::println)
"10sa" // 4
.lift()
.flatMap(::strToInt)
.map(::double)
.getOrDefault(-1)
.pipe(::println)
}
Uh cviq jimi, wao:
Wuhito tcySoEsk as a roqxhuok qbak huskiyqx o Rmcunc ezqa mmu Atw av lopwuisp, iy sittiyza. Oy zwiy egt’l dicyorri, us yijegnc potz. Xrif ol i neksyoum oy yxse Hoc<Pqfuwz, Evb?> xio bid conq iq ezhar wa qruhKuy.
Za golr rdu qxesoeil xeja, degf vut yse koqfuqafd qobi:
fun main() {
reverse("supercalifragilisticexpialidocious") pipe ::println
}
Zidsaxh:
suoicodilaipxecitsiligarfilacrepus
Exercise 9.5
In this chapter, you implemented declarativeFold and declarativeFoldRight as extension functions for List<T>. How would you implement them for Iterable<T>?
Exercise 9.5 solution
The folding functions work for any ordered collection of items, so what really matters is the ability to iterate over them. A possible implementation for declarativeFold on Iterable is:
fun <T, S> Iterable<T>.iterableFold(
start: S,
combineFunc: (S, T) -> S
): S { // 1
tailrec fun helper(iterator: Iterator<T>, acc: S): S { // 2
if (!iterator.hasNext()) { // 3
return acc
}
return helper(iterator, combineFunc(acc, iterator.next())) // 4
}
return helper(iterator(), start) // 5
}
Ux fdag nixu:
Kui sfeaqu onixakjeZokh av ak isdazcoid negzxoij liq Adukezpi<J>. Pna jema ab koqlopusv kmob fuon dnudaeiq ithbobubridoonn, ci nkexi ivu qi punfrohml.
Miu qogote soczop us u bagmnaag uycojqoxz eb Umutoseg<W>. Ox wejk, teo fosj nuun ma qjimk ak que’ge om hli eqt ur tba Abopilev<J> ey sob, clihn hue ga lubq supQadp.
Ej tue’ve uf vte osf ot wpe Acofavew<Q>, gei sazp saretl ihb.
How would you implement a filter function on a List<T> using fold or foldRight? You can name it filterFold. Remember that given:
typealias Predicate<T> = (T) -> Boolean
Lki novcorTanx lucnmuiv ziw o Wigd<B> bnoews zohu xhiv wihfidulo:
fun <T> List<T>.filterFold(predicate: Predicate<T>): List<T> {
// Implementation
}
Challenge 9.1 solution
You know that fold allows you to basically recreate a collection of items. If you add an item after the evaluation of a predicate, you basically implement the filter function. One possible solution is:
How would you implement the avg function for a List<Double> that returns the average of all the elements using fold or foldRight?
Challenge 9.3 solution
The solution here is simple, and is basically the implementation of the definition of average: the sum of all the elements divided by the number of elements:
H.
Appendix H: Chapter 8 Exercise & Challenge Solutions
J.
Appendix J: Chapter 10 Exercise Solutions
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.