【问题标题】:Haskell Nested List ComprehensionsHaskell 嵌套列表理解
【发布时间】:2019-08-20 00:42:17
【问题描述】:

我正在为考试而学习,我正在查看“Learn you a Haskell”一书中的嵌套列表理解示例,我希望有人可以逐步解释我如何分析它并得出结论它的输出。

let xxs = [[1,2,3],[2,3,4],[4,5]]

[ [ x | x <- xs, even x] | xs <- xxs ]] 

输出:([[2],[2,4],[4]])

【问题讨论】:

    标签: list function haskell nested list-comprehension


    【解决方案1】:
    [ [ x | x <- xs, even x] | xs <- xxs ]
    [ [ x | x <- xs, even x] | xs <- [[1,2,3],[2,3,4],[4,5]] ]
    [ [ x | x <- [1,2,3], even x] , [ x | x <- [2,3,4], even x] , [ x | x <- [4,5], even x] ]
    [filter even [1,2,3], filter even [2,3,4], filter even [4,5]]
    [[2],[2,4],[4]]
    

    或者

    [ [ x | x <- xs, even x] | xs <- xxs ]
    map (\xs -> [ x | x <- xs, even x] ) xxs
    map (\xs -> filter even xs) [[1,2,3],[2,3,4],[4,5]]
    [filter even [1,2,3], filter even [2,3,4], filter even [4,5]]
    [[2],[2,4],[4]]
    

    请注意,这不是 GHC 实际所做的转换,只是一种可能有助于您理解输出的编写方式。

    【讨论】:

      【解决方案2】:

      列表推导可以由几个身份定义:

      [ f x | x <- [],  ... ]       ===   []
      [ f x | x <- [y], ... ]       ===   [ f y | {y/x}... ]   -- well, actually, it's
                                          -- case y of x -> [ f y | {y/x}... ] ; _ -> []
      
      [ f x | x <- xs ++ ys, ...]   ===   [ f x | x <- xs, ...] ++ [ f x | x <- ys, ...]
      
      [ f x | True, ...]            ===   [ f x | ... ]
      [ f x | False, ...]           ===   []
      

      复杂 模式(相对于简单的变量模式)的处理被省略了,只是为了简单起见。 {y/x}... 表示,yx 替换为 ...。具体定义见the Report

      这样

      [ f x | xs <- xss, x <- xs]   ===  concat [ [f x | x <- xs] | xs <- xss] 
      

      [ f x | x <- xs, test x ]     ===  map f (filter test xs)
      

      你的表达相当于

      [ [ x | x <- xs, even x] | xs <- xxs ]   -- `]`, sic!
      =
      [ f xs | xs <- xxs ]  where  f xs = [ x | x <- xs, even x]
      

      也就是说,列表推导式在f 的定义中用作值表达式并没有什么特别之处。它看起来“嵌套”,但实际上并非如此。

      嵌套的,是用逗号分隔的生成器表达式:

      [ x | xs <- xss, x <- xs ]   ===   concat [ [x | x <- xs] | xs <- xss ]
      --              ^^^ nested generator
      

      (我们在上面看到的等价物。)那么,

      [ [ x | x <- xs, even x] | xs <- [[1,2,3],[2,3,4],[4,5]] ]
      =
      [ [ x | x <- [1,2,3], even x]] ++ [[ x | x <- [2,3,4], even x]] ++ [[ x | x <- [4,5], even x] ]
      =
      [ [ x | x <- [1,2,3], even x], [ x | x <- [2,3,4], even x], [ x | x <- [4,5], even x] ]
      =
      [ [ x | x <- [1], even x]++[ x | x <- [2], even x]++[ x | x <- [3], even x]
      , [ x | x <- [2], even x]++[ x | x <- [3], even x]++[ x | x <- [4], even x]
      , [ x | x <- [4], even x]++[ x | x <- [5], even x] ]
      =
      [ [ 1 | even 1]++[ 2 | even 2]++[ 3 | even 3]
      , [ 2 | even 2]++[ 3 | even 3]++[ 4 | even 4]
      , [ 4 | even 4]++[ 5 | even 5] ]
      =
      [ []++[ 2 ]++[], [ 2 ]++[]++[ 4 ], [ 4 ]++[] ]
      =
      [ [2], [2,4], [4] ]
      

      或者,如果您愿意,可以使用filter

      [ [ x | x <- [1,2,3], even x], [ x | x <- [2,3,4], even x], [ x | x <- [4,5], even x] ]
      =
      [ filter even [1,2,3], filter even [2,3,4], filter even [4,5] ]
      =
      [ [2], [2,4], [4] ]
      

      【讨论】:

        猜你喜欢
        • 2011-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-25
        • 1970-01-01
        • 2013-08-07
        相关资源
        最近更新 更多