Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference in capability between fmap and bind?

Tags:

I'm new to functional programming (coming from javascript), and I'm having a hard time telling the difference between the two, which is also messing with my understand of functors vs. monads.

Functor:

class Functor f where     fmap :: (a -> b) -> f a -> f b 

Monad (simplified):

class Monad m where     (>>=) :: m a -> (a -> m b) -> m b 
  • fmap takes a function and a functor, and returns a functor.
  • >>= takes a function and a monad, and returns a monad.

The difference between the two is in the function parameter:

  • fmap - (a -> b)
  • >>= - (a -> m b)

>>= takes a function parameter that returns a monad. I know that this is significant, but I'm having difficulty seeing how this one slight thing makes monads much more powerful than functors. Can someone explain?

like image 237
m0meni Avatar asked Feb 14 '16 01:02

m0meni


People also ask

What do you know about the functor and monad?

A functor takes a pure function (and a functorial value) whereas a monad takes a Kleisli arrow, i.e. a function that returns a monad (and a monadic value). Hence you can chain two monads and the second monad can depend on the result of the previous one. You cannot do this with functors.

Why applicative functor?

Applicative functors allow you to take a "normal" function (taking non-functorial arguments) use it to operate on several values that are in functor contexts. As a corollary, this gives you effectful programming without monads.

What is applicative in functional programming?

In functional programming, an applicative functor, or an applicative for short, is an intermediate structure between functors and monads.


1 Answers

Well, (<$>) is an alias for fmap, and (=<<) is the same as (>>=) with the arguments swapped:

(<$>) :: (x ->   y) -> b x -> b y (=<<) :: (x -> b y) -> b x -> b y 

The difference is now fairly clear: with the bind function, we apply a function that returns a b y rather than a y. So what difference does that make?

Consider this small example:

foo <$> Just 3 

Notice that (<$>) will apply foo to 3, and put the result back into a Just. In other words, the result of this computation cannot be Nothing. On the contrary:

bar =<< Just 3 

This computation can return Nothing. (For example, bar x = Nothing will do it.)

We can do a similar thing with the list monad:

foo <$> [Red, Yellow, Blue]   -- Result is guaranteed to be a 3-element list. bar =<< [Red, Yellow, Blue]   -- Result can be ANY size. 

In short, with (<$>) (i.e., fmap), the "structure" of the result is always identical to the input. But with (=<<) (i.e., (>>=)), the structure of the result can change. This allows conditional execution, reacting to input, and a whole bunch of other things.

like image 193
MathematicalOrchid Avatar answered Oct 19 '22 23:10

MathematicalOrchid