In order to understand Monad, I came up with the following definitions:
class Applicative\' f where
purea :: a -> f a
app :: f (a->b) -> f a ->
Monads are often easier understood with the “mathematical definition”, than with the methods of the Haskell standard class. Namely,
class Applicative' m => Monadd m where
join :: m (m a) -> m a
Note that you can implement the standard version in terms of this, vice versa:
join mma = mma >>= id
ma >>= f = join (fmap f ma)
For lists, join
(aka concat
) is particularly simple:
join :: [[a]] -> [a]
join xss = [x | xs <- xss, x <- xs] -- xss::[[a]], xs::[a]
-- join [[1],[2]] ≡ [1,2]
For the example you find confusing, you'd have
[1,2,3,4] >>= \x->[(x+1)]
≡ join $ fmap (\x->[(x+1)]) [1,2,3,4]
≡ join [[1+1], [2+1], [3+1], [4+1]]
≡ join [[2],[3],[4],[5]]
≡ [2,3,4,5]