Sometimes it's hard to tell if Haskell is the most beautiful language
or the most abstract nonsense. ;)

Amen. ;-)
 

Let's look at the Monad instance for the function (r -> a):

instance Monad ((->) r) where
   -- return :: a -> (r -> a)
   return a = \_ -> a

   -- (>>=) :: (r -> a) -> (a -> r -> b) -> (r -> b)
   left >>= right = \r -> right (left r) r


'return' creates a function ignoring its argument and just returning 'a'.

'>>=' creates a function with the argument 'r'. The function 'left' is
called with 'r' and the function 'right' is called with the result of
'left' and 'r'.


Now let's look at the 'sequence' function:

sequence ms = foldr k (return []) ms
   where
      k m ms = do
         x  <- m
         xs <- ms
         return (x : xs)


It's easier to see what happens if we rewrite 'k':

k m ms = m >>= (\x -> (ms >>= \xs -> return (x : xs)))


We saw that '>>=' creates a function with one argument, that argument
is the String containing the file contents, 'x' is the return value
of one "sequenced" function which is combined (:) with the previous
ones.

At the end we have the function (String -> [String]).

I will look at this more in depth this week-end, really thank you for the heads up! This stuff is really a bit crazy, but somehow I still like it ;-)

Emmanuel