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
Haskell 函数程序中的终止检查_Haskell_Agda_Denotational Semantics - Fatal编程技术网

Haskell 函数程序中的终止检查

Haskell 函数程序中的终止检查,haskell,agda,denotational-semantics,Haskell,Agda,Denotational Semantics,是否有函数语言可以在typechecker中指定某个计算是否保证终止?或者,您可以在Haskell中完成此操作吗? 关于Haskell,海报上说 通常认为,每个Haskell类型都是“提升的”——它包含⊥. 也就是说,Bool对应于{⊥, True,False}而不仅仅是{True,False}。这表明Haskell程序不保证终止,并且可能存在异常 另一方面,缔约国表示 正确的Agda程序是通过类型检查和 终止检查 即,所有Agda程序将终止,Agda中的Bool与{True,False}完全对

是否有函数语言可以在typechecker中指定某个计算是否保证终止?或者,您可以在Haskell中完成此操作吗?

关于Haskell,海报上说

通常认为,每个Haskell类型都是“提升的”——它包含⊥. 也就是说,
Bool
对应于
{⊥, True,False}
而不仅仅是
{True,False}
。这表明Haskell程序不保证终止,并且可能存在异常

另一方面,缔约国表示

正确的Agda程序是通过类型检查和 终止检查

即,所有Agda程序将终止,Agda中的
Bool
{True,False}
完全对应


例如,在Haskell中,可以有一个类型为
ioa
的值,它告诉typechecker需要IO来计算有问题的值。您是否可以使用一种类型的来声明所讨论的计算可能不会终止?也就是说,您允许不终止,但在类型系统中将其分开。(显然,就像在Agda中一样,您只能将值分为“明确终止”和“可能不终止”)如果没有,是否有语言可以做到这一点?

您当然可以。然而,这并不完美。根据定义,一些终止的计算必须驻留在
中。这就是所谓的停顿问题

在你放弃这个想法之前,这并不像听起来那么糟糕。Coq、Agda和其他许多方法都可以很好地使用启发式方法来检查终止

这一点真正重要的语言是Coq和Agda,在这些语言中,你试图证明定理。例如,假设我们有

 Definition falsy := exists n, n > 0 /\ 0 > n.
 -- Read this as, 
 --   "The type of a proof that for some number n, n > 0 and n < 0"
其中,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。现在这是非常困难的,因为,
falsy
是错误的。显然,不存在小于或大于0的数字

但是,如果我们允许使用无界递归进行非终止

 Definition bottom_proof : falsy = bottom_proof.
此类型检查,但明显不一致!我们只是证明了一些错误!因此,定理证明助手强制执行某种形式的终止检查,否则它们就一文不值了

如果你想务实一点,你可以使用这个提升的类型来告诉typechecker,“退后,我知道这可能不会终止,但我同意”。这对于编写真实世界的东西很有帮助,比如说,一个Web服务器或者任何你想让它“永远”运行的地方

本质上,你是在提出语言的划分,一方面,你有“验证代码”,你可以安全地证明事情,另一方面,你有“不安全代码”,它可能永远循环。您与
IO
的比较是正确的。这与Haskell的副作用划分完全相同

编辑:手写数据 您提到了corecursive数据,但这并不是您想要的。这个想法是你永远都在循环,但你这样做是“有成效的”。本质上,对于递归,检查终止的最简单方法是,始终使用严格小于当前值的项进行递归

Fixpoint factorial n := match n with
  | 0 => 1
  | S n' => n * factorial n'
使用corecursion,结果项必须比输入“大”

Cofixpoint stream := Cons 1 stream
同样,这不允许

 Cofixpoint stream := stream

我不知道有多少种编程语言。我能想到:阿格达;Coq;数据记录;SQL SELECT语句的一些变体(在没有函数和递归公共表表达式的情况下)。请注意,所有这些语言都不是图灵完备的。我个人希望有一种函数式编程语言,其中图灵完成(非终止)和异常处理是可选功能,类似于Haskell中IO的副作用。您提供的链接提到了“corecursion”和“codata”;也许这就是我想要的?我不确定这是一个多么有趣的评论。有没有可能,你可以把你的评论变成这个问题的真实答案,在这个问题上,你可以详细阐述一下,如果你放弃图灵完整性,你如何创建总函数?你为什么不考虑Coq和Agda?我敢肯定,人们已经发明了很多技巧来表示和处理这些语言中的非终止术语(例如,将一个可能的非终止函数转换成一个明确的终止函数,有时返回“尚未完成,请运行我一段时间”而不是实际的答案).Agda在其标准库中包含,可以将其视为提升的
类型构造函数。对全部函数的要求并不意味着您不能编写永远运行的Web服务器。科达塔在这方面其实很在行。(还有一个小问题,我认为你在开始时使用“按定义”是不公平的。停顿问题的不可判定性肯定是一个重要的定理。)
 Cofixpoint stream := stream