Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kleisli Arrow with Writer in Scala. Why doesn't it compile?

This is a followup to my previous question. Looks like I still did not get it. Now I am trying to compose functions that return Writer monad.

scala> val f = {x:Int => Writer("doing " + x + ";", x + 1)}
f: Int => scalaz.WriterT[scalaz.Id.Id,String,Int] = 

scala> Kleisli(f) >=> Kleisli(f)
:16: error: no type parameters for method apply: (f: A => M[B])scalaz.Kleisli[M,A,B] in object Kleisli exist so that it can be applied to arguments (Int => scalaz.WriterT[scalaz.Id.Id,String,Int])
 --- because ---
argument expression's type is not compatible with formal parameter type;
 found   : Int => scalaz.WriterT[scalaz.Id.Id,String,Int]
 required: ?A => ?M

              Kleisli(f) >=> Kleisli(f)

Why doesn't it compile ?

like image 346
Michael Avatar asked Dec 05 '25 04:12

Michael


1 Answers

When the Scala compiler expects a type shaped like M[B] and you give it something like WriterT[Id, String, Int], it's unfortunately just not smart enough to figure out that you want to fix the first two type parameters and use the monad for WriterT[Id, String, _].

There are a few possible ways to work around this limitation. The first is to define a type alias:

type StringWriter[A] = WriterT[Id, String, A]

Now you can provide explicit type parameters (in fact you could do this without the alias, but the type lambdas would make the line twice as long and ten times as unreadable):

scala> Kleisli[StringWriter, Int, Int](f) >=> Kleisli[StringWriter, Int, Int](f)
res0: scalaz.Kleisli[StringWriter,Int,Int] = Kleisli(<function1>)

Scalaz now provides a nicer solution, though, via Miles Sabin's "unapply trick":

val ff = Kleisli.kleisliU(f) >=> Kleisli.kleisliU(f)

kleisliU is essentially just a nice version of Kleisli.apply that uses a new type class (named Unapply) behind the scenes to guide the type inference system to the right way to break apart the WriterT[Id, String, Int].

like image 124
Travis Brown Avatar answered Dec 08 '25 01:12

Travis Brown



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!