Haskell,列表理解输出空列表。为什么?

Haskell, list comprehension outputs empty list. Why?

[x:ys | x<-[1,2], ys<-[]]

以上代码输出 []。我认为它应该输出 [1,2].

那么我对 Haskell 评估有什么误解?

你的期望有两个问题:

  1. x:ys 总是创建一个新列表; x:[] == [x],不是 x:[] == x
  2. 即使x:[] == x,事实仍然是ys <- []没有将名称ys分配给空列表;它将 ys 分配给空列表中的值 contained(当然,没有这样的值分配给 ys)。

您可以将 ys <- [] 更改为 ys <- [[]],在这种情况下您会得到

> [x:ys | x<-[1,2], ys<-[[]]]
[[1], [2]]

但是如果你想要[1,2],简单的列表理解就是

> [x | x <- [1,2]]
[1,2]

不涉及其他列表,因为您不需要列表列表作为答案。

列表理解表示嵌套循环:

[x:ys | x<-[1,2], ys<-[]]
 ==
do { x<-[1,2] ; do { ys<-[] ; return (x:ys) } }
 ==
{ for each x in [1,2]: { for each ys in []: yield (x:ys) } }
 == 
{ { for each ys in []: yield (1:ys) }     
; { for each ys in []: yield (2:ys) }     
}
 == 
{ { for none: yield ... } ; { for none: yield ... } }
 == 
{ none ; none }
 == 
none.

这让人联想到矩阵乘法:

join [ {- for 1: -}  [ a,b,c   ],       [  1a, 1b, 1c,
       {- for 2: -}  [ d,e     ],   =      2d, 2e,
       {- for 3: -}  [ f,g,h,i ],          3f, 3g, 3h, 3i
        ]                                                 ]

因此,如果为第一个列表的每个元素生成的列表为空,则总列表也为空,因为 concat [ [], [], [] ] == [].

另请参阅: