我正在为考试而学习,我正在看《学习Haskell》一书中嵌套列表理解的示例,我希望有人能逐步解释我如何分析它并得出结论。它的输出。
let xxs = [[1,2,3],[2,3,4],[4,5]]
[ [ x | x <- xs, even x] | xs <- xxs ]]
输出:([[2],[2,4],[4]])
答案 0 :(得分:2)
[ [ 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实际进行的转换,只是一种编写方式可以帮助您理解输出。
答案 1 :(得分:1)
列表理解可能由少数身份定义:
[ 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}...
表示用y
代替x
中的...
。有关实际定义,请参见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] ]