Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About the function monad

Tags:

haskell

monads

I have some confusion with the function monad. The function monad is defined as follow:

instance Monad ((->) r) where
     return x = \_ -> x
     h >>= f = \w -> f (h w) w

I tried to play around with it by writing a binding operation:

( (*2) >>= (+10) ) 3 

(return 3) :: ((->) Int)

But it caused errors. And I also try to rewrite a function AddStuff into the binding operations.

addStuff = do
           a <- (*2)
           b <- (+10)
           return (a+b)

then convert this function into

addStuff' w = (*2)  w >>= (\a ->
              (+10) w >>= (\b ->
              return (a+b) ))

I check the type of the new function as see

addStuff :: (Monad m, Num (m b), Num b) => m b -> m b 

Why is that? How can I fix that?

like image 453
chipbk10 Avatar asked Jan 20 '13 23:01

chipbk10


People also ask

What is the purpose of a monad?

A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.

What is a monad example?

Monads are simply a way to wrapping things and provide methods to do operations on the wrapped stuff without unwrapping it. For example, you can create a type to wrap another one, in Haskell: data Wrapped a = Wrap a. To wrap stuff we define return :: a -> Wrapped a return x = Wrap x.

What is monad simple?

So in simple words, a monad is a rule to pass from any type X to another type T(X) , and a rule to pass from two functions f:X->T(Y) and g:Y->T(Z) (that you would like to compose but can't) to a new function h:X->T(Z) . Which, however, is not the composition in strict mathematical sense.

What are monadic operations?

monadic operation (unary operation) defined on a set S. A function from the domain S into S itself. The identity function is a monadic operation. Other examples are the operations of negation in arithmetic or logic and of taking complements in set theory or in Boolean algebra.


1 Answers

In addStuff' you write (*2) w and (+10) w. Those are equivalent to w*2 and w+10 respectively. So addStuff' is equivalent to this:

addStuff' w = w*2 >>= \a ->
              w+10 >>= \b ->
              return (a+b)

Writing it this way should make it obvious that here the left operands to >>= are numbers, not functions. That's why the inferred type is telling you that your function only works for numbers that are monads.

When eliminating do notation the left operand to >>= should be exactly the same as the right operand of <-. Also eliminating do notation does not add any arguments to the function. So the correct rewriting would look like this:

addStuff' = (*2) >>= \a ->
            (+10) >>= \b ->
            return (a+b)

As to why your earlier pieces of code don't work:

( (*2) >>= (+10) ) 3 

The operator >>= has type m a -> (a -> m b) -> m b. For simplicity let's assume that all the numbers in this code have type Int, then your left operand has type Int -> Int or m Int if m is (->) Int. So for some type b the right operand should have type Int -> ((->) Int) b or, more readably, Int -> Int -> b. The type it actually has though is Int -> Int. Therefore your expression is ill-typed.

(return 3) :: ((->) Int)

((->) Int) has kind * -> * - the type of a value must have kind *.

Or to approach this differently: return 3 has type m Int for some m (still assuming that all integer literals have type Int for simplicity). So if m is ((->) Int), the type of return 3 will be ((->) Int) Int or Int -> Int, not ((->) Int).

like image 125
sepp2k Avatar answered Oct 16 '22 00:10

sepp2k