Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 无限列表的有限理解_Haskell - Fatal编程技术网

Haskell 无限列表的有限理解

Haskell 无限列表的有限理解,haskell,Haskell,我在ghci中输入了以下内容,认为会发生两件事之一:1)解释器将挂起,搜索无限列表中的每个成员以查找与谓词的匹配项;或者2)透过窗帘后面的哈斯凯尔柔术,口译员会不知何故发现序列终止于4,并在那里停止 [x | x <- [1..],5>x] [x | x] 结果1是发生了什么。现在,结果2有很多要求。但是,既然人类可以证明序列在4处终止,那么有没有办法让解释器这样做呢?是否可以将其改写为终止?事实上,有没有一个谓词能从无限的列表中做出有限的理解 但是,既然人类可以证明序列在4处终

我在ghci中输入了以下内容,认为会发生两件事之一:1)解释器将挂起,搜索无限列表中的每个成员以查找与谓词的匹配项;或者2)透过窗帘后面的哈斯凯尔柔术,口译员会不知何故发现序列终止于4,并在那里停止

[x | x <- [1..],5>x]
[x | x]
结果1是发生了什么。现在,结果2有很多要求。但是,既然人类可以证明序列在4处终止,那么有没有办法让解释器这样做呢?是否可以将其改写为终止?事实上,有没有一个谓词能从无限的列表中做出有限的理解

但是,既然人类可以证明序列在4处终止,那么有没有办法让解释器这样做呢

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

即使您的表达式仅限于基本的整数运算,在一般情况下,其真实性仍然是不可判定的

是否可以将其改写为终止


正如Mog在评论中所说,这是一个
takeWhile(<5)[1..]

takewhile
是上述特定问题的正确解决方案

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

这是一个用户界面问题

Prolog有
cut
操作符;在Haskell中,我们可以提前指定需要多少解决方案。就像在您的复杂示例(在注释中)中一样,
take 5$map f[1..]
可以工作,但是
take 6…
仍然会进入循环。为了克服这一点,我们需要一个运行时系统,它是一个定理证明器(正如其他人所说),和/或一个时间感知的多线程乐观推测部分求值器,它将为每个用户请求打开实时“应答框”。这可能需要使用优先级值(也在语言级别)标记计算

我认为这在任何意义上都是非常实际的。它让我们不用编写直观的简单代码,这是等式推理方法的最初承诺。最初,代码将以常规Haskell模式执行,但由于计算滞后,分析器将启动

无论如何,口译员大部分时间都是空闲的。大多数情况下,计算机也是如此


(稍后添加)参见,例如-“安全、可编程、推测并行性框架”

当然,其中“编译后的代码在运行时根据代码执行配置文件的试探法进行动态优化(并重新优化)”

“但既然人类可以证明序列在4点终止,可能 有办法让口译员来做吗?”


好问题。困难的不是证明它在4处终止,而是它可能在4处终止的想法,然后是它确实如此的洞察力。

takeWhile(<5)[1..]
@Mog:虽然我同意你的评论,既然你已经改变了理解的含义,这难道不是作弊吗?人类证明某个程序的能力并不总是自动程序可以模仿的:你可以推理某个特定程序可以终止,但一般来说,这是不可能计算的(这是无法确定的停顿问题).你可以在列表理解中编写任何你想要的代码,所以我相信在一般情况下,编译器将很难推理你的列表理解。我确实同意这是欺骗,但无论是通过这种方式还是通过使用
Data.list.Ordered
,你都必须在这里帮助Haskell一点,不是吗?@gcbenison:
takeWhile
不是灵丹妙药。它只有在所需的输出列表是输入列表的前缀时才起作用。因此,您是否同意@Kilian的观点:“可以向解释器添加符号推理,以便它可以证明没有其他元素可接受,然后终止”?@gcbenison:是和否。是的,这可能是可能的。不,它在一般情况下不起作用,因此口译员只能在某些情况下猜出正确的答案。要么语言必须彻底改变,要么你把口译员变成定理证明者。@larsmans“把口译员变成定理证明者”不管怎么说,这是我在堆栈溢出上看到的第一个关于停止问题的引用。解决方案是好的,但是解释一下为什么挂起是有用的。只有当我阅读时,我才意识到自己是多么的愚蠢。对于“滞后计算”,你的意思是运行时实际上会启动一个分析器来分析那些花费太长时间(如在挂钟时间)才能完成的代码吗?@gcbenison类似的情况。即使在这次给出答案之后,编译器也可以在后台做更多的工作,以找到更多的优化等。当然,这些都是假设。我认为这更像是一个讨论点,而不是问题的答案。真的吗