[Haskell-cafe] A good video on monad

Luke Palmer lrpalmer at gmail.com
Mon Jan 3 10:12:35 CET 2011


On Sun, Jan 2, 2011 at 11:48 PM, C K Kashyap <ckkashyap at gmail.com> wrote:
> Hi,
> I found this nice video on monads (although for clojure).
>
> http://www.youtube.com/watch?v=ObR3qi4Guys
>
> Question - in the video, if I understood right, the guy implements
> "return" as a function that takes a value and returns a function
> (action) that takes nothing and returns that value.
> And upon executing the action (essentially invoking the function that
> takes void) you get the value. So, what is the correct way of thinking
> about the similarity(if any) between a function taking 0 parameters
> and a single parameter type constructor?

Based on some of your phrasing, I think you are a Haskell beginner.
Sorry if I misread -- if not, this message will be full of stuff you
already know.

I haven't watched the video, but I think I see the deeper question you
are trying to ask.

When you say "function taking zero parameters" I think you are
referring to an action. In Haskell a "function taking zero parameters"
is just a value.  But in impure languages, or even in pure
call-by-value languages, there is a distinction.

You can make a type constructor corresponding to basically anything
you want -- it's just a lambda abstraction over types with some extra
syntax to help the compiler.  Here's one corresponding to the second
argument of a particular function type.

    newtype IntFunc2 a = IntFunc2 (Int -> a -> Int)

Or the return value of a function.

    newtype IntFunc a = IntFunc (Int -> a)

There's one for plain old values:

    newtype Value a = Value a

Which would be the Haskell version of your "function taking zero
arguments".  But for impure languages, you might call something an
"action":

    newtype Action a = ???

Of course we cannot give a definition for a side-effectful action in a
pure language, unless we precisely characterize the side-effects.  But
you can pretend the side-effects are characterized but we just don't
know how -- and with this you get basically Haskell's IO type
constructor.

The similarity you are looking for begins to appear when you consider
covariant type constructors, aka functors. Value, Action, IntFunc all
have something in common: that you can map a function over their
return value.

    mapValue :: (a -> b) -> Value a -> Value b
    mapValue f (Value a) = Value (f a)
    mapIntFunc :: (a -> b) -> IntFunc a -> IntFunc b
    mapIntFunc f (IntFunc f') = IntFunc (\x -> f (f' x))
    mapAction :: (a -> b) -> Action a -> Action b
    mapAction f action = "perform action and let x be the result, then
yield f x"

A functor is a special kind of one parameter type constructor, that
has one of these mapping operations (called "fmap").  It means that
they treat their parameter in a particular way, roughly that they do
something kind of like returning it rather than depending on it.  Note
that you cannot write such a definition for IntFunc2.

So a type constructor representing a "function taking 0 parameters" in
either a pure or an impure language, yields a functor on the return
value, as does an action (when there is a difference). That functor is
also applicative, and it also forms a monad, and lots of other stuff.
But I thought functor would be especially relevant for some reason.

I think the key point of enlightenment to be gleaned here is that,
purely, there is a difference between a function taking 0 parameters
and an action.  These concepts only coincide when you allow functions
to "do things" as well as "return things", which Haskell does not.

I apologize if this was a bit hard to follow, I was kind of shooting
in the dark with this answer.  I hope it gave some guidance.

Luke



More information about the Haskell-Cafe mailing list