Can please someone explain the differences between Functor and Monad in the Scala context?
A while ago I wrote about that: http://gabrielsw.blogspot.com/2011/08/functors-applicative-functors-and.html (I'm no expert though)
The first thing to understand is the type ' T[X] ' : It's a kind of "context" (is useful to encode things in types and with this you're "composing" them) But see the other answers :)
Ok, now you have your types inside a context, say M[A] (A "inside" M), and you have a plain function f:A=>B ... you can't just go ahead and apply it, because the function expects A and you have M[A]. You need some way to "unpack" the content of M, apply the function and "pack" it again. If you have "intimate" knowledge of the internals of M you can do it, if you generalize it in a trait you end with
trait Functor[T[_]]{
def fmap[A,B](f:A=>B)(ta:T[A]):T[B]
}
And that's exactly what a functor is. It transforms a T[A] into a T[B] by applying the function f.
A Monad is a mythical creature with elusive understanding and multiple metaphors, but I found it pretty easy to understand once you get the applicative functor:
Functor allow us to apply functions to things in a context. But what if the functions we want to apply are already in a context? (And is pretty easy to end in that situation if you have functions that take more than one parameter).
Now we need something like a Functor but that also takes functions already in the context and applies them to elements in the context. And that's what the applicative functor is. Here is the signature:
trait Applicative[T[_]] extends Functor[T]{
def pure[A](a:A):T[A]
def <*>[A,B](tf:T[A=>B])(ta:T[A]):T[B]
}
So far so good. Now comes the monads: what if now you have a function that puts things in the context? It's signature will be g:X=>M[X] ... you can't use a functor because it expects X=>Y so we'll end with M[M[X]], you can't use the applicative functor because is expecting the function already in the context M[X=>Y] .
So we use a monad, that takes a function X=>M[X] and something already in the context M[A] and applies the function to what's inside the context, packing the result in only one context. The signature is:
trait Monad[M[_]] extends Applicative[M]{
def >>=[A,B](ma:M[A])(f:A=>M[B]):M[B]
}
It can be pretty abstract, but if you think on how to work with "Option" it shows you how to compose functions X=>Option[X]
EDIT: Forgot the important thing to tie it: the >>= symbol is called bind and is flatMap in Scala. (Also, as a side note, there are some laws that functors, applicatives, and monads have to follow to work properly).