How Monads correspond to the composition of a function

I know that all functions are related to composition. For example, if I have an arrow from A to B and an arrow from B to C, then I also have an arrow from A to C.

But for (>>=)

his type Monad m => m a -> (a -> m b) -> m b

. Why is m a

it equal here a

?

I was wondering why not Monad m => m a -> (m a -> m b) -> m b

? It makes sense?

+3


source to share


4 answers


@ Sibi's answer is right, it doesn't make sense or would be helpful for monads to be defined as second signature. But related to your question about the relationship between function composition and monadic composition, there is an alternative way to look at the operator.

Monads have a bunch of alternative constructs that are equivalent to bind / return. One of these refers to an operator (<=<)

called the Kleisley composition operator, which composes monadic operations structurally similar to how functions are composed.

Arrows

Functions          : a -> b
Monadic operations : a -> m b

      



Composition:

-- Function composition
(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> g (f x)

-- Monad composition
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
f <=< g ≡ \x -> g x >>= f 

      

Gabriel Gonzalez wrote a nice blog post about this pattern: http://www.haskellforall.com/2012/08/the-category-design-pattern.html

+6


source


Try to implement this function yourself and you will find that it is useless:

func :: Monad m => m a -> (m a -> m b) -> m b
func x f = f x

      



So, you are basically suggesting to apply a value to a function. I don't think we need a special function for that. :-) The whole point >>=

is that it performs a side effect of the first parameter and then passes the resulting value to that function to the function.

+6


source


>>=

does not match composition, it matches (upside-down) application. The flipped version =<<

makes it clear:

($)   ::              (a ->   b) ->   a ->   b
(=<<) :: (Monad m) => (a -> m b) -> m a -> m b

      

($)

takes a unary function and applies it to the value, giving the value; =<<

takes a unary action and applies it to the result of the null action, giving the null action.

Operators matching composition to <=<

and >=>

from Control.Monad

:

(.)   ::              (b ->   c) -> (a ->   b) -> a ->   c
(<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> a -> m c

      

(.)

consists of two unary functions, giving a unary function; <=<

consists of two unary actions, giving a single action.

+5


source


If you are reordering the type signature it will make a lot more sense to you ....

Let modify

be (→ =) with a reversal of the order

modify::Monad m => (a -> m b) -> m a -> m b

      

or by adding implied parentheses

modify::Monad m => (a -> m b) -> (m a -> m b)

      

Now it's clear what's going on .... We are given a "one-sided" function that cannot be piped into a fixed datatype and converted to a function that can ... These functions work better with them since you can add and remove them at will to the pipeline, apply N times, even reordering them. (good, for a=b, at least

)

The pattern is very common .... a->m b

for example it could be a function that takes a value of val and may or may not return a value or an error.

+1


source







All Articles