Haskell,列表理解输出空列表。为什么?
Haskell, list comprehension outputs empty list. Why?
[x:ys | x<-[1,2], ys<-[]]
以上代码输出 []
。我认为它应该输出 [1,2]
.
那么我对 Haskell 评估有什么误解?
你的期望有两个问题:
x:ys
总是创建一个新列表; x:[] == [x]
,不是 x:[] == x
。
- 即使
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 [ [], [], [] ] == []
.
另请参阅:
[x:ys | x<-[1,2], ys<-[]]
以上代码输出 []
。我认为它应该输出 [1,2]
.
那么我对 Haskell 评估有什么误解?
你的期望有两个问题:
x:ys
总是创建一个新列表;x:[] == [x]
,不是x:[] == x
。- 即使
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 [ [], [], [] ] == []
.
另请参阅: