John Herrlin
10/10/2022, 8:04 AMproduct
to be called first and if that succeeds add
should be called.
But in the following code product
and add
is called concurrently. How can I make them not concurrent? 😃
import java.io.IOException
import arrow.core.computations.either
import arrow.core.Either
import arrow.core.Either.Left
import arrow.core.Either.Right
import arrow.core.getOrHandle
data class Error(val errorString: String, val exception: Exception?)
fun <A> remote(f: () -> A): A = if (Math.random() > 0.2) f() else throw IOException("boom!")
fun <A> trap(errorString: String, f: () -> A): Either<Error, A> =
try { Right(f()) }
catch (e: Exception) { Left(Error(errorString, e)) }
fun multiply(a: Int, b: Int): Either<Error, Int> = trap("multiplication failed") { remote { a * b } }
fun add(a: Int, b: Int): Either<Error, Int> = trap("addition failed") { remote { a + b } }
// If fetching `product` is failing `sum` should not be called at all.
suspend fun calculate(a: Int, b: Int): Either<Error, Int> =
either<Error, Int> {
val product = multiply(a, b).bind()
val sum = add(a, b).bind()
sum }
suspend fun main() {
println(calculate(2, 10).getOrHandle { it.errorString })
println(calculate(2, 10).getOrHandle { it.errorString })
}
Sam
10/10/2022, 8:11 AMJohn Herrlin
10/10/2022, 8:23 AM#+HEADER: :classpath /Users/john.herrlin/.m2/repository/io/arrow-kt/arrow-core-jvm/1.1.3/arrow-core-jvm-1.1.3.jar:/Users/john.herrlin/.m2/repository/io/arrow-kt/arrow-continuations-jvm/1.1.3/arrow-continuations-jvm-1.1.3.jar
#+BEGIN_SRC kotlin :results output code
import java.io.IOException
import arrow.core.computations.either
import arrow.core.Either
import arrow.core.Either.Left
import arrow.core.Either.Right
import arrow.core.getOrHandle
data class Error(val errorString: String, val exception: Exception?)
fun <A> remote(f: () -> A): A = throw IOException("boom!")
fun <A> trap(errorString: String, f: () -> A): Either<Error, A> =
try { Right(f()) }
catch (e: Exception) { Left(Error(errorString, e)) }
fun multiply(a: Int, b: Int): Either<Error, Int> {
println("running multiply")
return trap("multiplication failed") { remote { a * b } }
}
fun add(a: Int, b: Int): Either<Error, Int> {
println("running add")
return trap("addition failed") { a + b }
}
suspend fun calculate(a: Int, b: Int): Either<Error, Int> =
either<Error, Int> {
val product = multiply(a, b).bind()
val sum = add(a, b).bind()
sum }
suspend fun main() {
println(calculate(2, 10).getOrHandle { it.errorString })
println(calculate(2, 10).getOrHandle { it.errorString })
println(calculate(2, 10).getOrHandle { it.errorString })
}
#+END_SRC
#+RESULTS:
#+begin_src kotlin
running multiply
multiplication failed
running multiply
multiplication failed
running multiply
multiplication failed
#+end_src
John Herrlin
10/10/2022, 8:23 AMSam
10/10/2022, 8:24 AM