I've searched through the Slack channel however a ...
# arrow
k
I've searched through the Slack channel however a lot of the discussion I found was in 2020 and I think Arrow has significantly changed since then. I'm hoping to get some help on how to do Kliesli compositions in Arrow. I have a data structure and a bunch of functions that operate on that data, which return an
Either
. For example
(Int) -> Either<Error, Int>
. I can use monandic comprehensions ie:
Copy code
val c = either {
  val a = func1(1).bind()
  val b = func2(a).bind()

  b
}
However I want to create a pipe/composition to remove the intermediate variables. In pseudo code
Copy code
val pipe = func2 composeK func1
val c = pipe(1)
Is this possible?
p
Hey @kierans777, You can easily build Kleisli composition for Either yourself
Copy code
infix fun <A,E,B,C> ((A)->Either<E,B>).composeK(ff: (B)->Either<E,C>): (A)->Either<E,C> =
    { a: A -> this(a).flatMap(ff)}
As the Typeclasses have been dropped with 0.13, you can unfortunately no longer write one for Monads in general
If you want to use it with your above example, you'd have to swap the two arguments though 🙂
k
Thanks @Patrick Louis
As the Typeclasses have been dropped with 0.13, you can unfortunately no longer write one for Monads in general
As a newbie to Arrow, can you help me understand why Typeclasses were dropped? Or that the ability to compose functions returning monads together isn't in Arrow? For context, I've done FP in Crocks (Javascript) and Clojure so having to figure out how to map what I want to do to Kotlin/Arrow.
Just to make this harder, if I wanted to composeK suspended functions (because I'm doing something like IO) is the only way to use monadic comprehensions because you can't
flatMap
a suspended function?
p
The reasons for dropping typeclasses are mostly related to Kotlins lacking support for typeclasses and the bad code produced by the syntactic constructs to emulate them. But I think @raulraja can better elaborate on this matter than I can. regarding your question on suspend-function composition, this can be achieved by composing them inside a comprehension:
Copy code
suspend infix fun <A, E, B, C> (suspend (A) -> Either<E, B>).composeK(ff: suspend (B) -> Either<E, C>): suspend (A) -> Either<E, C> =
    { a: A -> either { ff(this@composeK(a).bind()).bind() } }
granted, it doesn't look as elegant as the previous version, but it works in a similar fashion.
k
Thanks @Patrick Louis. With both the two versions, the bit I don't understand is the use of
this
.
I'm newish to Kotlin so feel free to point me to some doco 🙂
p
The this refers to the receiver of the
composeK
function, so the
(suspend (A) -> Either<E, B>)
part
k
That's a really neat solution.