John Herrlin
10/10/2022, 8:04 AMproductaddproductaddimport 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_srcJohn Herrlin
10/10/2022, 8:23 AMSam
10/10/2022, 8:24 AM