为GHC

2021-02-20 17:32

中的术语分配文字出于好奇,为什么以下程序1=0quot;=quot;由GHC有效并可编译?这仅仅是一个bug还是一个特性?谢谢!

解答动态

  • 这是允许的,因为它是语言规则的自然结果,并且没有问题到足以在语言规范中做一个特例来阻止它。
    自然结果有两种标准的定义:函数定义和数据定义。在函数定义中,可以将模式作为参数写入等号左侧的函数。在数据定义中,您可以在等号左侧单独编写一个模式,以与等号右侧的数据相匹配。所以,这些都是允许:
    x=3倍@y=3[x,y,z]=[3,4,5][x,216;,z]=[3,4,5][x,4,z]=[3,4,5]x:216;=quot;x:quot;=quot; 数字文字和字符串文字是模式。(以前的德斯加变成了一个叫(=)的守卫)所以这些是允许的,太:
    3=3倍@3=3[3,4,5]=[3,4,5]quot;=quot;——是的,这些too3=4quot;=quot; 与语言的所有其他部分没有问题,数据定义是惰性的:它们所表示的模式匹配计算直到需要时才执行(通过检查匹配所绑定的一个变量)。由于quot;=quot;和1=0不绑定任何变量,因此它们所表示的模式匹配计算(将引发异常)永远不会执行。所以不允许他们也不是特别重要。
    …除非是等待。。。我们说这是有效的图案:
    x@3=3这相似的一个分开并结合了一个变量:
    x@3=4 为什么允许这样做?这很难回答!我认为应该考虑一些语言规则来防止这种情况的发生。一般来说,一个合理而完整的规则当然是不可判定的,因为方程的右边可以进行任意计算。但你也可以做出其他选择,比如例如:不要允许在数据定义中使用可反驳的模式。如果一个模式不能匹配,它是可以反驳的。例如,x是无可辩驳的,x@y公司是无可辩驳的,u是无可辩驳的,但是x:y是可辩驳的,True是可辩驳的,()是可辩驳的(因为当RHS在底部时它会发散)。这是迄今为止最简单的,并且排除了x@3个=4和quot;=quot;都是。不幸的是,它还排除了像[x,y,z]=[3,4,5]这样非常有用的东西。实现一个终止检查器,并要求可反驳模式的rh终止。如果你有一个分析,可以决定一些计算终止——例如,通过发现其中所有的递归都是结构化的或者其他的,有一个完整的终止检查算法的家庭手工业——那么你可以让编译器检查它。如果它确实终止了,编译器实际上可以在编译期间运行计算,并再次检查给定的模式是否与值匹配。这样做的缺点是终止检查算法非常复杂,因此这给编译器编写者带来了很大的负担,而且有些算法很难被人类预测,这使得针对它的编程对于整个系统来说是令人沮丧的用户需求程序员证明匹配不会失败。你可以引入一种机制,让程序员为他们的程序编写证明,并要求他们证明匹配不会失败。这朝着依赖类型的方向发展;这样做的两个主要代价通常是程序效率的降低,用这样的语言编写程序需要付出更多的努力。 语言设计人员做出了许多选择(不仅仅是在模式匹配语义方面),这些选择有助于使程序员和编译器编写者的生活更轻松一些,但也允许一些错误更多从不完成或抛出异常的程序。这就是这样一个点——在数据定义中允许使用可反驳的模式,即使这会导致崩溃,因为该策略的实现是有用的、简单的和可预测的。

    • 因为这些文本是模式,所以您使用的是模式绑定。
      let在Haskell中绑定是懒惰的,所以没有实际的模式匹配被执行。
      但是如果我们强制匹配,它确实失败:
      gt;alt;interactive>;:87:1-7:模式的无可辩驳模式失败x@1 原因1实际上不是0.
      ,所以这不是一个bug,也不是GHC实现的特性,而是Haskell语言本身的特性

      • End

      免责声明:

      本页内容仅代表作者本人意见,若因此产生任何纠纷由作者本人负责,概与琴岛网公司无关。本页内容仅供参考,请您根据自身实际情况谨慎操作。尤其涉及您或第三方利益等事项,请咨询专业人士处理。