Hi, I wonder if anyone can help me with a question...
# arrow
d
Hi, I wonder if anyone can help me with a question on how to create a pipeline of transformation functions. Some of the functions return the type that is being operated on directly, and some functions return Either. Below is a contrived example of what I am trying to achieve. The part that I do not like is having to give a name to the intermediate values (i1, i2, etc). If they all returned a simple value (rather than some functions returning either), I could use 'andThen' to compose the functions together. Sorry for the simple question, but I struggle with how to accomplish stuff in a functional way sometimes.
Copy code
public suspend fun test(): Unit {
    val add1: (number: Int) -> Int = { it + 1 }

    suspend fun divideBy(number: Int, divideBy: Int): Either<Throwable, Int> {
        return Either.catch { number / divideBy }
    }

    val result = either<Throwable, Int> {
        val start = 1
        val i1 = add1(start)
        val i2 = !divideBy(i1, 2)
        val i3 = add1(i2)
        add1(i3)
    }

    result.fold(
        { println("failed: ${it.message}") },
        { println("result: $it") }
    )
}
s
You can rewrite this to:
Copy code
divideBy(add1(1), 2)
.map(add1)
.map(add1)
.fold(
  { println("failed: ${it.message}") },
  { println("result: $it") }
)
So here you can use
map
instead of
andThen
to compose a function that work on the inner value of
Either
.
s
+
flatMap
for
divideBy
d
Thanks. This has made my code much cleaner. I have a follow-up question, mainly for my own understanding. Is there a way to do this in a way that creates a composed function as opposed to operating on the result. For example, not considering the Either we can do:
Copy code
val add2 = add1 andThen add1
If feels like it should be possible to wrap the 'add1' function into a function that accepts an Either as an argument which would enable the functions to be composed together in a pipeline. Sorry if this is a silly question. I have the information I needed, I am just trying to learn a bit more 🙂
s
You can lift a function
(A) -> B
to a function
(Either<E, A>) -> Either<E, B>
by using
Either.lift
which is a function you'll also find in other places so.
Copy code
val add1: (number: Int) -> Int = { it + 1 }
val add2: (number: Int) -> Int = add1 andThen add1
val eitherAdd: (Either<String, Int>) -> Either<String, Int> = Either.lift(add2)
d
Thanks for the additional information. I haven't had time to digest the article yet, but I think what I am referring to is kleisli composition as explained in this Scala article: https://blog.ssanj.net/posts/2017-06-07-composing-monadic-functions-with-kleisli-arrows.html