My question is about the sequence
function in Prelude
, the signature of which is as follows:
sequence :: Monad m => [m a] -> m [a]
I understand how this function works for List
of Maybe
s. For example, applying sequence
on [Just 3, Just 9]
gives Just [3, 9]
.
I noticed that applying sequence
on List
of List
s gives its Cartesian Product. Can someone please help me understand how/why this happens?
This works because using lists as monads in Haskell makes them model indeterminism. Consider:
By definition this is the same as:
Just read it as "First a choice between 1 and 2, then a choice between 3 and 4". The list monad will now accumulate all possible outcomes - hence the answer
[[1,3],[1,4],[2,3],[2,4]]
.(for an even more obfuscated example, see here)
Just to explain, why the application of sequence to a list of lists is so different from the application of sequence to a list of Maybe-values:
When you apply
sequence
to a list of lists, then the type of sequence is specialized fromto (with the type constructor m set to [])
(which is the same as
sequence :: [[a]] -> [[a]]
)internally, sequence uses (>>=) -- i.e. the monadic bind function. For lists this bind function is implemented completly different than for m set to Maybe!
sequence
acts as if it were defined like this.(Or
sequence = foldr (liftM2 (:)) (return [])
but anyhow…)Just think about what happens when applied to a list of lists.