I am having difficulty understanding how a function can be a monad.
Function (->) r
is a monad according to a declaration in Control.Monad.Instances
:
instance Monad ((->) r) where
return x = \_ -> x
h >>= f = \w -> f (h w) w
Even what Miran Lipovača says about it makes me confused:
The implementation for
>>=
seems a bit cryptic, but it's really not all that. When we use>>=
to feed a monadic value to a function, the result is always a monadic value. So in this case, when we feed a function to another function, the result is a function as well. That's why the result starts off as a lambda. All of the implementations of>>=
so far always somehow isolated the result from the monadic value and then applied the function f to that result. The same thing happens here. To get the result from a function, we have to apply it to something, which is why we do(h w)
here to get the result from the function and then we apply f to that. f returns a monadic value, which is a function in our case, so we apply it to w as well.
The type signature of (>>=) is this: (>>=) :: m a -> (a -> m b) -> m b
So I take that h
is typed as m a
and f
as (a -> m b)
. If a function is m a
, does it return an a
type value? or does it return something else taking an a
type?
If the non-monad value of h
is fed to f
, then we get:
f (h w)
Looks fine. Since f
is a function and has taken its sole argument, it is already a value, no? Since it's a monadic function the value is also a monadic value. Why then does it need another value w
? Doesn't feeding w
to f something
make it non-monadic, i.e., it is not a function any more, no? I also cannot understand why f something
and h
take the same argument w
and return different value types (m a
and m b
).