【发布时间】:2017-07-14 06:05:09
【问题描述】:
This recent question 让我想到了 Haskell 处理无限列表的能力。 StackOverflow上有plentyofother关于无限列表的问题和答案,我明白为什么我们不能对所有无限列表都有一个通用的解决方案,但是为什么Haskell不能解释some 无限列表?
让我们使用第一个链接问题中的示例:
list1 = [1..]
list2 = [x | x <- list1, x <= 4]
print list2
$ [1,2,3,4
@user2297560 在 cmets 中写道:
假装你是 GHCI。您的用户给了您一个无限列表,并要求您找到该列表中小于或等于 4 的所有值。您将如何去做? (请记住,您不知道列表是有序的。)
在这种情况下,用户并没有给你一个无限列表。 GHC 生成它!事实上,它是按照自己的规则生成的。 Haskell 2010 Standard 声明如下:
enumFrom :: a -> [a] -- [n..]
对于 Int 和 Integer 类型,枚举函数的含义如下:
- 序列 enumFrom
e1是列表 [e1,e1+ 1,e1+ 2,…]。
@chepner 在回答另一个问题时写道:
你知道列表是单调递增的,但 Haskell 不知道。
在我看来,这些用户的陈述似乎不符合标准。 Haskell 使用单调递增以有序方式创建列表。 Haskell应该知道列表是有序且单调的。那么为什么不能将这个无限列表自动将[x | x <- list1, x <= 4] 变成takeWhile (<= 4) list1 呢?
【问题讨论】:
-
好。只是想把这个链接在这里。 stackoverflow.com/questions/40145318
-
Haskell 不会推断任何东西,除非该语言的开发人员对其进行推断。天下没有免费的午餐。显然,您可以设计语言,以便自动将某些列表标记为正在增加,但这会增加已经非常复杂的语言的复杂性。
-
@JohnColeman 这很公平,这对我来说似乎是管理无限列表的一个合乎逻辑的跳跃。我认为 Haskell 的设计人员/开发人员在语言设计/抽象数学方面更加精通,并且有一个很好的理论理由来解释为什么没有这样做,而不是一个务实的理由。
-
列表推导对所有类型的列表都适用,并且不考虑任何进一步的结构(即
[1..]的类型为Enum t, Num t => [t]而不仅仅是[t])。其次,谓词x <= 4对过滤机制是不透明的,它只是一个函数t -> Bool,因此随着列表元素的增加,没有关于其行为的信息。 -
正如其他人所提到的,一旦创建了一个列表,关于它的如何创建的信息就会丢失。你需要以某种方式保存它;典型的方法是创建自己的类型来保留订购信息。使您的类型符合
List类型类,您可以在任何适合普通Ord a => List a的地方使用它。
标签: list haskell ghc compiler-optimization