Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Hands-on Arrow
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Karin-Aleksandra Monoid
February 12, 2021
170
1
Share
Hands-on Arrow
Karin-Aleksandra Monoid
February 12, 2021
More Decks by Karin-Aleksandra Monoid
See All by Karin-Aleksandra Monoid
Extending kotlinx.serialization functionality with Arrow Meta (Joker 2021/KotlinDevDay 2022)
paranoidmonoid
0
130
Treasure.map(): Functional programming in JVM-based languages
paranoidmonoid
0
330
Extending kotlinx.serialization functionality with Arrow Meta
paranoidmonoid
0
120
Functional Kotlin with Arrow (jLove 2021)
paranoidmonoid
1
240
Make Tech Slides Work
paranoidmonoid
0
620
"Fun" as in "funeral": full-stack development using Kotlin JS
paranoidmonoid
0
120
Featured
See All Featured
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2k
The SEO identity crisis: Don't let AI make you average
varn
0
480
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.8k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
440
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
65
55k
Into the Great Unknown - MozCon
thekraken
41
2.5k
The Invisible Side of Design
smashingmag
302
52k
Scaling GitHub
holman
464
140k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
390
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
380
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
200
Transcript
Karin-Aleksandra Monoid GDG Nuremberg, 2021 Hands-on Arrow (How we filled
Kotlin standard library gaps without converting code to Scala)
Agenda • What is Arrow? • NonEmptyList • Either •
Monad Comprehensions
What is Arrow?
What is Arrow? 4 4 Core FX Optics Meta
What is Arrow? 5 5 Core FX Optics Meta
NonEmptyList
Non-empty list Is JSON {“payments”: []} ok? 7 7 Payments
List of items (Phone, Reference, Amount) Phone ... String(100) Required Reference ... String(100) Required Amount ... Decimal Required
Non-empty list NonEmptyList.of() // does not compile NonEmptyList.of(1, 2, 3,
4, 5) // NonEmptyList<Int> 8 8
Non-empty list NonEmptyList.of() // does not compile NonEmptyList.of(1, 2, 3,
4, 5) // NonEmptyList<Int> 9 9
Either
Java Exceptions if (somethingWrong) throw new SomeException(...) 11 11
Java Exceptions - “Handling” in signature void testFun() throws SomeException
12 12
Java Exceptions - Handling with try try { testFun() }
catch (SomeException e) { ... } 13 13
Java Exceptions IntStream.range(0, 10) .forEach(i -> testFun()) 14 14
Java Exceptions IntStream.range(0, 10) .forEach(i -> testFun()) 15 15
Java Exceptions IntStream.range(0, 10) .forEach(hideException(i -> testFun())); 16 16
Java Exceptions unhideSomeException(() -> IntStream.range(0, 10) .forEach( hideException(i -> testFun()
))); 17 17
Kotlin Exceptions • No more checked exceptions (like Scala, Groovy
and everyone else) 18 18
Kotlin Exceptions (1 until 10).forEach { testFun() } 19 19
Null fun String.toIntOrNull(): Int? • Not expressive • ????? •
null-checks 20 20
Result Type inline class Result<out T> : Serializable 21 21
Result Type 22 22 fun deserialize(): Something { return try
{ doSomething() } catch (_: Exception) { try { doSomethingElse() } catch(_: Exception) { doSomethingElseAgain() }}... fun deserialize(): Something { return runCatching { doSomething() }.recoverCatching { doSomethingElse() }.getOrElse { doSomethingElseAgain() } }
Sealed Type sealed class Result class Success : Result() class
FullMoonFailure : Result() class ElonMuskTweetedFailure : Result() 23 23
Either sealed class Either<out A, out B> 24 24
Validated sealed class Validated<out A, out B> 25 25
Validated vs Either • Either stops at first fail, validated
collects all: User(phone, name, age) User(“test”, XÆA-12 Musk, -10) • Either: invalid phone • Validated: invalid phone, name*, age 26 26 * https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/
Monad comprehensions
Require requireNotNull(request.userId) requireNotNull(request.transaction.id) 28 28
Require public inline fun <T : Any> requireNotNull (value: T?):
T { contract { returns() implies (value != null) } return requireNotNull(value) { "Required value was null." } } 29 29
if-else-if-else-if-else if(request.userId == null) return buildExceptionResponse(...) if(request.transaction.id == null) return
buildExceptionResponse(...) ... 30 30
Arrow Monads 31 31 https://chrisdone.com/posts/monads-are-burritos/
Arrow Monads 32 32 inline fun <T, R> Iterable<T>.flatMap( transform:
(T) -> Iterable<R> ): List<R>
Chaining - flatMap val response = checkForNull(...) .flatMap { userId
-> checkForNull(...).flatMap { paymentId -> checkForNull(...).flatMap { items -> checkForNull(...).flatMap { status -> checkForNull(...).map { ( … )}}}}}}}}} 33 33
Chaining - monad comprehensions val response = Either.fx { val
userId = checkForNull(request.userId).bind() val paymentId = checkForNull(request.transaction.id).bind() val items = checkForNull(request.transaction.items).bind() val status = client.checkPaymentStatus(userId,...) // ... } return response.getOrHandle { it } private fun <T : Any> checkForNull(param: T?, paramName: String): Either<ErrorResponse, T> 34 34
None