All combinations of elements of two lists in Haskell

前端 未结 5 1107
情歌与酒
情歌与酒 2020-12-30 03:42

Given two lists, [a, b] and [c, d], I\'d like to get the following result:

[(a,c), (a,d), (b         


        
5条回答
  •  情歌与酒
    2020-12-30 04:14

    How can you do this in an imperative pseudocode?

    for each element x in [a,b]:
        for each element y in [c,d]:
            produce (x,y)
    

    In Haskell, this is written as

    outerProduct xs ys =
       do
           x <- xs          -- for each x drawn from xs:
           y <- ys          --   for each y drawn from ys:
           return (x,y)     --      produce the (x,y) pair
    

    (following comments by leftaroundabout) this is of course extremely close to how liftM2 monadic combinator is defined, so in fact

    outerProduct = liftM2 (,)
    

    which is the same as liftA2 (,), and its various re-writes in terms of list comprehensions, concatMap function, >>=, <$> and <*> operators.

    Conceptually though this is the stuff of the Applicative – which would be better named as Pairing, – because this pairing up of the elements of two "containers" ⁄ "carriers" ⁄ whatever is exactly what Applicative Functor is about. It just so happens that Haskell's do notation works for monads, and not (yet) for applicatives.

    In some sense compile-time nested loops are Applicative ⁄ Pairing functors; Monads add the ability to create nested loops on the fly, depending on the values produced by an "outer" enumeration.

提交回复
热议问题