Scalaz adds some nice features to Scala.
In the Haskell world, "functions are applicative functors. They allow us to operate on the eventual results of functions as if we already had their results" (from LYAHFGG).
(Where the "Functor typeclass, ... is basically for things that can be mapped over", "all applicatives are functors" [1] and applicatives have a function that has a type of f (a -> b) -> f a -> f b.)
So, why can't we map over functions in Scala? Well, now with Scalaz, we can!
import scalaz._
import Scalaz._
val f: Int => Int = _ * 2
val g: Int => Int = _ + 10
val mapped = f.map(g)
println(mapped(7)) // "24", ie (7 * 2) + 10
which is the same as saying f.andThen(g) and so the opposite of saying f.compose(g).
We can also flatMap over functions now and as a result can use for comprehensions:
val addStuff: Int => Int = for {
a <- f
b <- g
} yield (a + b)
println("addStuff = " + addStuff(7)) // "31"
Why this monadic behaviour is so nice is that "the syntactic sugar of the for-comprehensions abstracts the details nicely enough for the user, who is completely oblivious of the underlying machinery of binding monads" (from here).
We can even raise a plain old Int to the level of monad with:
println(3.point[Id].map(_ + 1)) // prints out "4"
a <- f
b <- g
} yield (a + b)
println("addStuff = " + addStuff(7)) // "31"
Why this monadic behaviour is so nice is that "the syntactic sugar of the for-comprehensions abstracts the details nicely enough for the user, who is completely oblivious of the underlying machinery of binding monads" (from here).
We can even raise a plain old Int to the level of monad with:
println(3.point[Id].map(_ + 1)) // prints out "4"
By using point, the "constructor is abstracted out... Scalaz likes the name point instead of pure, and it seems like it’s basically a constructor that takes value A and returns F[A]." (from Learning Scalaz).
[1] Functional Programming in Scala (Chiusano and Bjarnason)
No comments:
Post a Comment