Apparently fmap is a useful thing in dealing with monads. Together with join, it allows to define the behaviour of a monad rather than using the pair unit+return. [Unfortunately for fmap and join, I have managed to do well with unit+return so far.]

If there is a function func1 implements F<A,B> you can promote it to a func2 implements F<Monad<A>,Monad<B>>. The latter carries inside itself the capability of doing the following, whenever we put it at work:

  1. unwrap the A from Monad<A>
  2. calculate the B as func1(A)
  3. rewrap it as a new Monad

There is a relevant example given by apocalisp, in which a function length, capable of measuring the length of strings (that’s not what you’d call a tough job to do, but it makes the point), is made exception-safe by creating a fmap(length) which can handle strings coming e.g. from reading a file. The interesting bit is that fmap(length) does not carry any throws FileNotFoundException in the signature, nor any try/catch block in its body.

I can imagine that fmap has something to say also outside the world of monads, but where? I think at a fmap(List<A>), but then I recollect that the Haskell sites say that also List<A> is a monad. Too bad…

In any case fmap looks interesting. Nice to know it exists, maybe one day I will apply it in a real-world problem.

One thought on “fmap

  1. Rúnar says:

    Hi Marco,

    A monad is a triple (map, unit, join). In various libraries, map is sometimes called fmap or liftM. Unit is sometimes called return or pure, and join is sometimes called flatten.

    If you think of an expression of type M[A], where M is some monad, as being inside brackets, then the map function carries knowledge of how to apply a function to an expression inside brackets. The unit function knows how to put a value into brackets (such that it’s an identity for join) and the join function knows how to remove inner brackets (satisfying associativity).

    You hit the nail on the head how map is useful for lists. It simply applies a given function to every value in the list, constructing a new list with the exact same structure as the old list.

    To possess fmap, a type construction does not need to be a monad. It suffices that it’s a functor. In fact, having fmap is what it means to be a functor. Therefore all monads are also functors. But for example a pair type (A,B) is not a monad in general, but it’s a functor twice over.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s