列表理解评估

发布于 2024-10-20 19:59:53 字数 314 浏览 1 评论 0原文

我不明白为什么下面两种情况会有所不同?因为懒惰评估?

1)

Main> [x:xs | x:xs <- tails [1,2,3]]
=> [[1,2,3], [2,3], [3]]

2)

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]]

I don't understand why below 2 case be different ? because of lazy evaluation?

1)

Main> [x:xs | x:xs <- tails [1,2,3]]
=> [[1,2,3], [2,3], [3]]

2)

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]]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无人接听 2024-10-27 19:59:53

它们的定义不同。展示这一点的最好方法是举一个例子。列表推导式试图找到所有可能的变量集,这些变量可以从列表中选择而不违反条件。如果您有多个变量,它将返回它们的每一种组合。例如:

[(x,y) | x <- [1,2,3], y <- [1,2,3]]

收益率:

[(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]

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

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

They are different by definition. The best way to show this, is an example. List comprehensions try to find all possible sets of variables, that can be choosed from the list without violating the condition. If you have more than one variable, it returns each combination of them. For instance:

[(x,y) | x <- [1,2,3], y <- [1,2,3]]

yields:

[(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]

What can we see? First, an element of the first list is chosen, than one of the second list. The result is a list of all possible ways of choosing x and y.

SO your second statement must of course yield the second result.

初心未许 2024-10-27 19:59:53

不,与惰性评估无关。

考虑第三种情况:

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]]

No, nothing to do with lazy evaluation.

Consider this third case:

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]]
内心荒芜 2024-10-27 19:59:53

另一种看待它的方式:

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 绘制为“对”,有点将它们“压缩”在一起。

ghci> zipWith (:) l1 l2
[[1,2,3],[2,3],[3]]

您的第二个推导式绘制了 xxs 的所有组合,并将它们与 (:) 组合起来。

ghci> (:) <
gt; l1 <*> l2
[[1,2,3],[1,3],[1],[2,2,3],[2,3],[2],[3,2,3],[3,3],[3]]

Another way to look at it:

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],[]]

Your first comprehension draws x and xs as a "pair", sort of keeping them "zipped" together.

ghci> zipWith (:) l1 l2
[[1,2,3],[2,3],[3]]

Your second comprehension draws all combinations of x and xs, combining them with (:).

ghci> (:) <
gt; l1 <*> l2
[[1,2,3],[1,3],[1],[2,2,3],[2,3],[2],[3,2,3],[3,3],[3]]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文