Tricky Kotlin #8: Simple for-comprehension
Description:
Let's build a simple for-comprehension DSL in kotlin!
Look, I have a function like this:
import java.util.Optional
fun plus(o1: Optional<Int>, o2: Optional<Int>): Optional<Int> {
if (o1.isPresent && o2.isPresent)
return Optional.of(o1.get() + o2.get())
else
return Optional.empty()
}
I can rewrite it with a more functional style:
fun plus(o1: Optional<Int>, o2: Optional<Int>): Optional<Int> =
o1.flatMap { i1 ->
o2.flatMap { i2 ->
Optional.of(i1 + i2)
}
}
o1.flatMap {...}
means if o1
is not empty, invoke the closure with the value wrapped in o1
and then use the result of the closure as the return value of flatMap
. Otherwise (if o1
is empty) discard the closure and simply return Optional.empty()
. As you can see, this code does the same thing as the original code.
In Scala, we can do it in a more elegant way called for-comprehension
.
// this is scala, not kotlin
def plus(o1: Option[Int], o2: Option[Int]) = {
for {
i1 <- o1
i2 <- o2
} yield i1 + i2
}
// it's equivalent to
// o1.flatMap(i1 => o2.flatMap(i2 => Some(i1 + i2)))
But Kotlin has no similar feature to achieve this!
So in this kata, your task is to build a simple for-comprehension DSL in Kotlin, enable you to write the following code (like Scala):
fun plus(o1: Optional<Int>, o2: Optional<Int>): Optional<Int> =
`for` {
val i1: Int = bind(o1)
val i2: Int = bind(o2)
yield(i1 + i2)
}
// it's required to be equivalent to
// o1.flatMap { i1 -> o2.flatMap { i2 -> Optional.of(i1 + i2) } }
Don't worry, this DSL is only used for java.util.Optional
, you don't need to deal with other types. Most of the test cases have already been provided for you. (
Similar Kata:
Stats:
Created | Jan 29, 2018 |
Published | Jan 31, 2018 |
Warriors Trained | 540 |
Total Skips | 77 |
Total Code Submissions | 331 |
Total Times Completed | 93 |
Kotlin Completions | 93 |
Total Stars | 32 |
% of votes with a positive feedback rating | 94% of 25 |
Total "Very Satisfied" Votes | 22 |
Total "Somewhat Satisfied" Votes | 3 |
Total "Not Satisfied" Votes | 0 |
Total Rank Assessments | 3 |
Average Assessed Rank | 3 kyu |
Highest Assessed Rank | 2 kyu |
Lowest Assessed Rank | 4 kyu |