【发布时间】:2013-02-05 00:53:44
【问题描述】:
我正在尝试理解Haskell 2010 Report section 3.17.2“模式匹配的非正式语义”。大多数情况下,与模式匹配成功或失败有关的情况似乎很简单,但是我很难理解被描述为模式匹配“发散”的情况。
我半信半疑,这意味着匹配算法不会“收敛”到答案(因此匹配函数永远不会返回)。但是,如果不返回,那么它如何返回一个值,如括号“即返回⊥”所建议的那样?无论如何,“返回⊥”是什么意思?如何处理这种结果?
第 5 项有一个特别令人困惑的(对我来说)点“如果值为 ⊥,则匹配发散”。这只是说⊥ 的值会产生⊥ 的匹配结果吗? (撇开我不知道那个结果意味着什么!)
任何照明,可能带有示例,将不胜感激!
经过几个冗长的答案后的附录: 感谢 Tikhon 和所有人的努力。
似乎我的困惑来自于有两个不同的解释领域:Haskell 特征和行为领域,以及数学/语义领域,在 Haskell 文献中,这两者混合在一起,试图用术语来解释前者后者,没有足够的路标(对我来说)关于哪些元素属于哪个元素。
显然“底部”⊥ 在语义域中,并且在 Haskell 中不作为值存在(即:您无法输入它,您永远不会得到打印为“⊥”的结果)。
因此,在解释中说函数“返回⊥”的地方,这是指执行许多不方便的事情的函数,例如不终止、抛出异常或返回“未定义”。对吗?
此外,那些评论 ⊥ 实际上 是 可以传递的值的人,实际上是在考虑绑定到尚未实际调用评估的普通函数 ("未爆炸的炸弹”可以这么说)而且可能永远不会,因为懒惰,对吧?
【问题讨论】:
-
返回 undefined 就像抛出异常一样——
undefined就是这样定义的。是的,传递底部是可能的,只是因为 Haskell 并不严格,而这些值确实类似于未爆炸的炸弹。 -
但是在 Haskell 中,程序中没有任何东西实际上知道(或可以测试)一个值“是”一个底部,直到/除非它被实际调用并产生效果,此时它是一个实际的异常,未定义或非终止,对吗? (仍在尝试确定“底部”是否是 Haskell 中的实际值,而不是语义概念,对思考有用但不是实际值)。
-
是的,你不能测试它。考虑不终止的情况:你怎么知道评估不会终止?一般情况下是无法确定的。如果您手上有一个无限循环,那么您实际上并没有正常值,但您确实有
⊥。我希望能澄清一些事情——正如我回答中的 cmets 所示,我想不出一个好的方式来描述它。 -
好的,谢谢。我认为对我的大脑来说,这意味着底部不是实际的 Haskell 值或类型。这是一个词/符号,用来讨论可能返回未定义、可能不返回或可能异常的函数。至于您答案中的 cmets,它们本身就有助于展示讨论和思考的各种方式。再次感谢。
-
了解
⊥的“不可测试性”(在 Haskell 中)的一个非常重要的方法是了解单调性。有很长的路要走(这解释了 Haskell 语义的 CPO 域)或很短的路:⊥的完整语义是您无法对其进行模式匹配。任何“最终”构造函数可以匹配它(False、True、3、[]),但一旦你这样做,匹配的语义就会被感染,也只是⊥。因此,任何匹配无限循环的函数都是无限循环。与undefined相同,错误也几乎相同(请注意,spoon之类的库违反了这一点)。