Sun Jan 10 11:40:33 CET 2010
To make things more intuitive I'm calling the parameterized data types
that are members of the type class Functor and Applicative
``collections''. (I find a fixed-size array most intuitive.)
Functor: A functor is a collection that supports an operation `fmap'
which maps A SINGLE transformation of elements to a transformation of
class Functor f where
fmap :: (a -> b) -> f a -> f b
Applicative: An applicative functor is a collection that supports the
operation `<*>' which maps A COLLECTION of transformations to a
transformation of collections.
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
In addition a function `pure' is required that wraps an element into a
collection. The operations need to satisfy some laws:
pure id <*> v = v -- Identity
pure (.) <*> u <*> v <*> w = u <*> (v <*> w) -- Composition
pure f <*> pure x = pure (f x) -- Homomorphism
u <*> pure y = pure ($ y) <*> u -- Interchange
In  it is mentioned that this can be used for side-effects -- hence
the name `pure'. I don't quite get that.