首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >列表理解测评

列表理解测评
EN

Stack Overflow用户
提问于 2011-03-05 20:15:37
回答 3查看 297关注 0票数 1

我不明白为什么下面两个案例是不同的?因为懒惰的评估?

1)

代码语言:javascript
运行
复制
Main> [x:xs | x:xs <- tails [1,2,3]]
=> [[1,2,3], [2,3], [3]]

2)

代码语言:javascript
运行
复制
Main> [x:xs | x:xs' <- tails [1,2,3], x':xs <- tails [1,2,3]]
=> [[1,2,3],[1,3],[1], [2,2,3],[2,3],[2],[3,2,3],[3,3],[3]]
EN

回答 3

Stack Overflow用户

发布于 2011-03-05 20:27:38

它们在定义上是不同的。最好的方式来说明这一点,是一个例子。列表理解试图找到所有可能的变量集,这些变量集可以从列表中选择,而不违反条件。如果您有多个变量,它将返回这些变量的每个组合。例如:

代码语言:javascript
运行
复制
[(x,y) | x <- [1,2,3], y <- [1,2,3]]

收益率:

代码语言:javascript
运行
复制
[(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]

我们能看到什么?首先,选择第一列表中的元素,而不是第二列表中的元素。结果是选择x和y的所有可能方法的列表。

所以你的第二个语句当然必须产生第二个结果。

票数 2
EN

Stack Overflow用户

发布于 2011-03-05 21:27:14

不,与懒惰评估无关。

考虑第三种情况:

代码语言:javascript
运行
复制
Prelude Data.List> [x:xs | x:xs' <- tails [1,2,3], x':xs <- tails [1,2,3], x == x']
[[1,2,3],[2,3],[3]]
票数 1
EN

Stack Overflow用户

发布于 2011-03-06 01:03:11

另一种看待它的方式:

代码语言:javascript
运行
复制
ghci> :m +Data.List
ghci> :m +Control.Applicative
ghci> let l1 = [x | x:xs <- tails [1,2,3]]
ghci> l1
[1,2,3]
ghci> let l2 = [xs | x:xs <- tails [1,2,3]]
ghci> l2
[[2,3],[3],[]]

您的第一个理解是将xxs作为“一对”,将它们“拉紧”在一起。

代码语言:javascript
运行
复制
ghci> zipWith (:) l1 l2
[[1,2,3],[2,3],[3]]

您的第二个理解是绘制xxs的所有组合,并将它们与(:)相结合。

代码语言:javascript
运行
复制
ghci> (:) <$> l1 <*> l2
[[1,2,3],[1,3],[1],[2,2,3],[2,3],[2],[3,2,3],[3,3],[3]]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5203751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档