I am trying to use >=>
(Kleisli arrow) in Scala. As I understand, it composes functions returning monads. Now I am trying it as follows:
scala> val f = {i:Int => Some(i + 1)} f: Int => Some[Int] = <function1> scala> val g = {i:Int => Some(i.toString)} g: Int => Some[String] = <function1> scala> val h = f >=> g <console>:15: error: value >=> is not a member of Int => Some[Int] val h = f >=> g ^
Why does not it compile ? How to compose f
and g
with >=>
?
There are two problems here. The first is that the inferred types of your functions are too specific.
Option
is a monad, butSome
is not. In languages like Haskell the equivalent ofSome
isn't even a type—it's just a constructor—but because of the way algebraic data types are encoded in Scala you have to watch out for this issue. There are two easy fixes—either provide the more general type explicitly:Or use Scalaz's handy
some
, which returns an appropriately typedSome
:The second problem is that
>=>
isn't provided for plain old monadic functions in Scalaz—you need to use theKleisli
wrapper:This does exactly what you want—just use
h.run
to unwrap.