Suppose I have a few functions Int => Int
composed with andThen
:
val f1: Int => Int = _ + 1
val f2: Int => Int = _ + 2
val f3: Int => Int = _ + 3
val f = f1 andThen f2 andThen f3
Now I need to return also the intermediate results. So I can convert all those functions to Int => (List[Int], Int)
where the list contains the arguments.
I can probably use Writer[List[Int], Int]
of scalaz
to represent the pair (List[Int], Int)
:
val fw1: Int => Writer[List[Int], Int] = x => f1(x).set(List(x))
val fw2: Int => Writer[List[Int], Int] = x => f2(x).set(List(x))
val fw3: Int => Writer[List[Int], Int] = x => f3(x).set(List(x))
In order to compose fw1
, fw2
, and fw3
I probably need to wrap them with Kleisli
. However Kleisli(fw1)
does not compile since Writer[List[Int], Int]
is not a monad.
I guess that I probably need a monad transformer
to make Writer[List[Int], Int]
a monad but I don't know exactly how to do it. So, my question is: how to make Kleisli(fw1)
compile with a monad transformer ?
Writer[List[Int], ?]
does have a monad instance—this is just a case where scalac isn't able to see that without a little help. You can just usekleisliU
, which is likeKleisli.apply
but with some type inference help fromUnapply
(which is described here and in a number of other places):And then:
You could also provide explicit type parameters for
Kleisli.apply
orKleisli.kleisli
.