Why does application of `sequence` on List of Lists lead to computation of its Cartesian Product?

后端 未结 3 512
死守一世寂寞
死守一世寂寞 2020-12-24 11:58

My question is about the sequence function in Prelude, the signature of which is as follows:

sequence :: Monad m => [m a] ->          


        
相关标签:
3条回答
  • 2020-12-24 12:23

    This works because using lists as monads in Haskell makes them model indeterminism. Consider:

    sequence [[1,2],[3,4]]
    

    By definition this is the same as:

    do x <- [1,2]
       y <- [3,4]
       return [x,y]
    

    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)

    0 讨论(0)
  • 2020-12-24 12:24

    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 from

    sequence :: Monad m => [m a] -> m [a]
    

    to (with the type constructor m set to [])

    sequence :: [[] a] -> [] [a] 
    

    (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!

    0 讨论(0)
  • 2020-12-24 12:38

    sequence acts as if it were defined like this.

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

    (Or sequence = foldr (liftM2 (:)) (return []) but anyhow…)

    Just think about what happens when applied to a list of lists.

    sequence [] = [[]]
    sequence (list : lists) =
        [ x : xs
        | x <- list
        , xs <- sequence lists
        ]
    
    0 讨论(0)
提交回复
热议问题