有限理解无限列表

时间:2012-04-26 15:18:35

标签: haskell

我在ghci中输入以下内容,认为会发生以下两种情况之一:1)解释器会挂起,搜索无限列表中的每个成员以匹配谓词;或者2)通过幕后的Haskell jujitsu,解释器会以某种方式弄清楚序列终止于4并停在那里。

[x | x <- [1..],5>x]

结果1是发生了什么。现在,结果2有很多要求。但是既然人类可以证明序列终止于4,那么可能有办法让翻译来做吗?这可以以它终止的方式重写吗?事实上,是否有永远一个谓词,它从无限列表中进行有限理解?

4 个答案:

答案 0 :(得分:23)

  

但是既然人类可以证明序列终止于4,那么可能有办法让解释者去做吗?

在这个简单的例子中,是的。但是对于某些>n,不存在用于确定表达式对于所有自然数n是真还是假的通用算法,因为Haskell是图灵完备的,因此不可能证明表达式甚至表示所有自然数的终止程序。

即使你的表达仅限于基本的整数算术,在一般情况下它的真实性仍然是不可判定的。

  

是否可以以终止它的方式重写?

正如Mog在评论中所写,它是takeWhile (< 5) [1..]

答案 1 :(得分:7)

如上所述,

takewhile是针对您的具体问题的正确解决方案。

然而,这只是因为在你的情况下,所有可接受的参数都出现在所有不可接受的参数之前,并且一般列表理解不遵守该约束。当然可以向解释器添加符号推理,以便它可以证明没有其他元素可以接受然后终止。 (实际上,Haskell中复杂的类型系统在实现这样的推理时非常有用。)但是将它添加到标准[|]运算符是没有意义的,因为检测器必须在上运行评估的所有列表推导,除了更多的计算费用之外,通常都无法做出任何贡献。

答案 2 :(得分:2)

  

“但是,由于人类可以证明序列终止于4,可能   有办法让口译员去做吗?“

好问题。困难的事情并不是它终止于4的证据,而是它可能终止于4的想法,然后是洞察力确实如此。

答案 3 :(得分:0)

这是一个用户界面问题。

Prolog有cut运营商;在Haskell中,我们可以提前指定我们期望的解决方案数量。就像您的复杂示例(在评论中)一样,take 5 $ map f [1..]会起作用,但take 6 ...仍会进入循环。为了解决这个问题,我们需要一个运行时系统,它是一个定理证明器(正如其他人所说),和/或一个时间感知的多线程乐观的推测性部分评估器,可以打开“每个用户请求的答案框。这将需要可能标记具有优先级值的计算(也在语言级别)。

我认为从各方面来说,这都是非常实用。它让我们逃避编写直观的简单代码,这无论如何都是等式推理方法的最初承诺。最初,代码将以常规Haskell模式执行,但随后分析器将启动,以防止滞后计算。

无论如何,口译员大部分时间都处于空闲状态。主要是计算机。


稍后添加)请参阅,例如the speculation package - “安全,可编程,推测并行的框架”

当然还有V8,其中“编译代码在运行时根据代码执行配置文件的启发式”进行动态优化(并重新优化)。