### 问题

This is the signature of the well know >>= operator in Haskell

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

The question is why type of the function is

```
(a -> m b)
```

instead of

```
(a -> b)
```

I would say the latter one is more practical because it allows straightforward integration of existing "pure" functions in the monad being defined.

On the contrary, it seems not difficult to write a general "adapter"

```
adapt :: (Monad m) => (a -> b) -> (a -> m b)
```

but anyway I regard more probable that you already have `(a -> b)`

instead of `(a -> m b)`

.

**Note.** I explain what I mean by "pratical" and "probable".
If you haven't defined any monad in a program yet, then, the functions you have are "pure" `(a -> b)`

and you will have 0 functions of the type `(a -> m b)`

just because you have not still defined `m`

. If then you decide to define a monad `m`

it comes the need of having new `a -> m b`

functions defined.

### 回答1:

Basically, `(>>=)`

lets you sequence operations in such a way that latter operations can choose to behave differently based on earlier results. A more pure function like you ask for is available in the `Functor`

typeclass and is derivable using `(>>=)`

, but if you were stuck with it alone you'd no longer be able to sequence operations at all. There's also an intermediate called `Applicative`

which allows you to sequence operations but not change them based on the intermediate results.

As an example, let's build up a simple IO action type from Functor to Applicative to Monad.

We'll focus on a type `GetC`

which is as follows

```
GetC a = Pure a | GetC (Char -> GetC a)
```

The first constructor will make sense in time, but the second one should make sense immediately—`GetC`

holds a function which can respond to an incoming character. We can turn `GetC`

into an `IO`

action in order to provide those characters

```
io :: GetC a -> IO a
io (Pure a) = return a
io (GetC go) = getChar >>= (\char -> io (go char))
```

Which makes it clear where `Pure`

comes from---it handles pure values in our type. Finally, we're going to make `GetC`

abstract: we're going to disallow using `Pure`

or `GetC`

directly and allow our users access only to functions we define. I'll write the most important one now

```
getc :: GetC Char
getc = GetC Pure
```

The function which gets a character then immediately considers is a pure value. While I called it the most important function, it's clear that right now `GetC`

is pretty useless. All we can possibly do is run `getc`

followed by `io`

... to get an effect totally equivalent to `getChar`

!

```
io getc === getChar :: IO Char
```

But we'll build up from here.

As stated at the beginning, the `Functor`

typeclass provides a function exactly like you're looking for called `fmap`

.

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

It turns out that we can instantiate `GetC`

as a `Functor`

so let's do that.

```
instance Functor GetC where
fmap f (Pure a) = Pure (f a)
fmap f (GetC go) = GetC (\char -> fmap f (go char))
```

If you squint, you'll notice that `fmap`

affects the `Pure`

constructor only. In the `GetC`

constructor it just gets "pushed down" and deferred until later. This is a hint as to the weakness of `fmap`

, but let's try it.

```
io getc :: IO Char
io (fmap ord getc) :: IO Int
io (fmap (\c -> ord + 1) getc) :: IO Int
```

We've gotten the ability to modify the return type of our `IO`

interpretation of our type, but that's about it! In particular, we're still limited to getting a single character and then running back to `IO`

to do anything interesting with it.

This is the weakness of `Functor`

. Since, as you noted, it deals only with pure functions it gets stuck "at the end of a computation" modifying the `Pure`

constructor only.

The next step is `Applicative`

which extends `Functor`

like this

```
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
```

In other words it extends the notion of injecting pure values into our context *and* allowing pure function *application* to cross over the data type. Unsurprisingly, `GetC`

instantiates `Applicative`

too

```
instance Applicative GetC where
pure = Pure
Pure f <*> Pure x = Pure (f x)
GetC gof <*> getcx = GetC (\char -> gof <*> getcx)
Pure f <*> GetC gox = GetC (\char -> fmap f (gox char))
```

Applicative allows us to sequence operations and that might be clear from the definition already. In fact, we can see that `(<*>)`

pushes character application forward so that the `GetC`

actions on either side of `(<*>)`

get performed in order. We use `Applicative`

like this

```
fmap (,) getc <*> getc :: GetC (Char, Char)
```

and it allows us to build incredibly interesting functions, much more complex than just `Functor`

would. For instance, we can already form a loop and get an infinite stream of characters.

```
getAll :: GetC [Char]
getAll = fmap (:) getc <*> getAll
```

which demonstrates the nature of `Applicative`

being able to sequence actions one after another.

The problem is that we can't stop. `io getAll`

is an infinite loop because it just consumes characters forever. We can't tell it to stop when it sees `'\n'`

, for instance, because `Applicative`

s sequence without noticing earlier results.

So let's go the final step an instantiate `Monad`

```
instance Monad GetC where
return = pure
Pure a >>= f = f a
GetC go >>= f = GetC (\char -> go char >>= f)
```

Which allows us immediately to implement a stopping `getAll`

```
getLn :: GetC String
getLn = getc >>= \c -> case c of
'\n' -> return []
s -> fmap (s:) getLn
```

Or, using `do`

notation

```
getLn :: GetC String
getLn = do
c <- getc
case c of
'\n' -> return []
s -> fmap (s:) getLn
```

So what gives? Why can we now write a stopping loop?

Because `(>>=) :: m a -> (a -> m b) -> m b`

lets the second argument, a function of the pure value, *choose* the next action, `m b`

. In this case, if the incoming character is `'\n'`

we choose to `return []`

and terminate the loop. If not, we choose to recurse.

So that's why you might want a `Monad`

over a `Functor`

. There's much more to the story, but those are the basics.

### 回答2:

The reason is that `(>>=)`

is more general. The function you're suggesting is called liftM and can be easily defined as

```
liftM :: (Monad m) => (a -> b) -> (m a -> m b)
liftM f k = k >>= return . f
```

This concept has its own type class called `Functor`

with `fmap :: (Functor m) => (a -> b) -> (m a -> m b)`

. Every `Monad`

is also a `Functor`

with `fmap = liftM`

, but for historical reasons this isn't (yet) captured in the type-class hierarchy.

And `adapt`

you're suggesting can be defined as

```
adapt :: (Monad m) => (a -> b) -> (a -> m b)
adapt f = return . f
```

Notice that having `adapt`

is equivalent to having `return`

as `return`

can be defined as `adapt id`

.

So anything that has `>>=`

can also have these two functions, but not vice versa. There are structures that are Functors but not Monads.

The intuition behind this difference is simple: A computation within a monad can depend on the results of the previous monads. The important piece is `(a -> m b)`

which means that not just `b`

, but also its "effect" `m b`

can depend on `a`

. For example, we can have

```
import Control.Monad
mIfThenElse :: (Monad m) => m Bool -> m a -> m a -> m a
mIfThenElse p t f = p >>= \x -> if x then t else f
```

but it's not possible to define this function with just `Functor m`

constraint, using just `fmap`

. Functors only allow us to change the value "inside", but we can't take it "out" to decide what action to take.

### 回答3:

As others have said, your bind is the `fmap`

function of the `Functor`

class, a.k.a `<$>`

.

But why is it less powerful than `>>=`

?

it seems not difficult to write a general "adapter"

`adapt :: (Monad m) => (a -> b) -> (a -> m b)`

You can indeed write a function with this type:

```
adapt f x = return (f x)
```

However, this function is not able to do everything that we might want `>>=`

's argument to do. There are useful values that `adapt`

cannot produce.

In the list monad, `return x = [x]`

, so `adapt`

will always return a single-element list.

In the `Maybe`

monad, `return x = Some x`

, so `adapt`

will never return `None`

.

In the `IO`

monad, once you retrieved the result of an operation, all you can do is compute a new value from it, you can't run a subsequent operation!

etc. So in short, `fmap`

is able to do fewer things than `>>=`

. That doesn't mean it's useless -- it wouldn't have a name if it was :) But it is less powerful.

### 回答4:

The whole 'point' of the monad really (that puts it above functor or applicative) is that you can determine the monad you 'return' based on the values/results of the left hand side.

For example, `>>=`

on a `Maybe`

type allows us to decide to return `Just x`

or `Nothing`

. You'll note that using functors or applicative, it is impossible to "choose" to return `Just x`

or `Nothing`

based on the "sequenced" Maybe.

Try implementing something like:

```
halve :: Int -> Maybe Int
halve n | even n = Just (n `div` 2)
| otherwise = Nothing
return 24 >>= halve >>= halve >>= halve
```

with only `<$>`

(`fmap1`

) or `<*>`

(`ap`

).

Actually the "straightforward integration of pure code" that you mention is a significant aspect of the functor design pattern, and is very useful. However, it is in many ways unrelated to the motivation behind `>>=`

--- they are meant for different applications and things.

### 回答5:

I think that J. Abrahamson's answer points to the right reason:

Basically, (>>=)

lets you sequence operationsin such a way that latter operations can choose to behave differently based on earlier results. A more pure function like you ask for is available in the Functor typeclass and is derivable using (>>=), but if you were stuck with it aloneyou'd no longer be able to sequence operations at all.

And let me show a simple counterexample against `>>= :: Monad m => m a -> (a -> b) -> m b`

.

It is clear that we want to have values bound to a context. And perhaps we will need to *sequentially chain* functions over such "context-ed values". (This is just one use case for Monads).

Take `Maybe`

simply as a case of "context-ed value".

Then define a "fake" monad class:

```
class Mokad m where
returk :: t -> m t
(>>==) :: m t1 -> (t1 -> t2) -> m t2
```

Now let's try to have `Maybe`

be an instance of `Mokad`

```
instance Mokad Maybe where
returk x = Just x
Nothing >>== f = Nothing
Just x >>== f = Just (f x) -- ????? always Just ?????
```

The first problem appears: `>>==`

is always returning `Just _`

.

Now let's try to chain functions over `Maybe`

using `>>==`

(we sequentially extract the values of three `Maybe`

s just to add them)

```
chainK :: Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int
chainK ma mb mc = md
where
md = ma >>== \a -> mb >>== \b -> mc >>== \c -> returk $ a+b+c
```

But, this code doesn't compile: `md`

type is `Maybe (Maybe (Maybe Int))`

because every time `>>==`

is used, it encapsulates the previous result into a `Maybe`

box.

And on the contrary `>>=`

works fine:

```
chainOK :: Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int
chainOK ma mb mc = md
where
md = ma >>= \a -> mb >>= \b -> mc >>= \c -> return (a+b+c)
```

来源：`https://stackoverflow.com/questions/21221705/on-the-signature-of-monad-operator`