[x:ys | x<-[1,2], ys<-[]]
以上代码输出[]
。我认为它应该输出[1,2]
。
那么我对Haskell评估的错误是什么?
答案 0 :(得分:3)
您的期望有两个问题:
x:ys
始终会创建一个新列表; x:[] == [x]
,而不是x:[] == x
。x:[] == x
,事实仍然是ys <- []
未将名称ys
分配给空列表;它将ys
分配给空列表中的包含值(当然,没有这样的值可以分配给ys
)。您可以将ys <- []
更改为ys <- [[]]
,在这种情况下,您将获得
> [x:ys | x<-[1,2], ys<-[[]]]
[[1], [2]]
但是如果你想要[1,2]
,那么简单的列表理解就是
> [x | x <- [1,2]]
[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 [ [], [], [] ] == []
。