I use arrow-kt library and I'm trying to employ Either
and IO
within the same for comprehension.
Say I have the next piece of code:
IO.monad().binding {
val ans: Either<Error, Data> = someFunctionThatReturnsEitherWrappedInIO().bind()
}
Now, I'd like to use binding on the ans
:
val data: Data = ans.bind() // My intent
Is it possible to do It whithin the scope of the first piece of code?
Currently I'm trying to nest an Either
binding within the scope of the IO binding, but I'm not sure this is a good practice:
IO.monad().binding {
val ans: Either<Error, Data> = someFunctionThatReturnsEitherWrappedInIO().bind()
val ansB: Either<Error, OtherData> = someOtherFunctionThatReturnsEitherWrappedInIO().bind()
val newData: Either<Any, NewData> = Either.monad<Any>().binding {
val data: Data = ans.bind()
val otherData: OtherData = ansB.bind()
NewData(data.a, otherData.lala)
}.fix()
}
First I should mention that Monads don't compose, that's why you need a Monad transformer, in your case EitherT
is the guy that can help you.
object Error
fun one() = IO { Right(1) }
fun two() = IO { Right("2") }
fun toInt(str: String) = IO { Try { str.toInt() }.toEither { Error } }
val result: IO<Either<Error, Int>> =
EitherT.monad<ForIO, Error>(IO.monad()).binding {
val oneInt = EitherT(one()).bind()
val twoString = EitherT(two()).bind()
val twoInt = EitherT(toInt(twoString)).bind()
oneInt + twoInt
}.value().fix()
println(result.unsafeRunSync()) // Just for demonstration, don't do this ever
Right(b=3)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With