[英]What is the role of 'bottom' (⊥) in Haskell function definitions?
底部本质上是说undefined
的奇特代数方式。
如果你试试这个,你就会明白为什么zip
的右手参数是懒惰的:
λ> zip [] undefined
[]
λ> zip undefined []
*** Exception: Prelude.undefined
这是因为undefined
只有在您尝试对其进行评估时才会失败。
由于它的呈现方式,您可能会将_|_
与_
混淆。 我会清楚:行zip [] _|_ = []
不作为模式匹配而公式,说明平等zip [] _|_
和[]
也就是说,这不是有效的 Haskell 代码,而是一种表示“我不在乎第二个参数”的符号化、抽象代数方式。
在zip
的定义中,您当然可以使用_
,但这无关紧要。 您可以使用任何名称,只要它不是构造函数匹配模式,例如(Just x)
或(a,b)
。 值将保持未计算状态,直到它们必须在纯代码中进行模式匹配。
您可以在此处阅读有关延迟评估的更多信息。
我认为 OP 已经意识到这一点,但为了其他同样困惑的人的利益: zip [] _|_ = []
不是实际代码!
符号_|_
(这仅仅是一个数学符号的ASCII艺术渲染⊥
)是指底部1,但只有当我们谈论哈斯克尔。 在 Haskell 代码中,它没有这个含义2 。
行zip [] _|_ = []
是对zip
实际代码属性的描述; 如果您使用第一个参数[]
调用它并将任何底部值作为第二个参数传递,则结果等于[]
。 他们之所以要这么说,是因为函数f
不严格的技术定义是当f ⊥
不是⊥
。
但是在定义 Haskell 函数(在代码中)时,没有_|_
(或⊥
,或undefined
,或底部的概念)的作用。 它是不可能的模式匹配上的参数,看看它是否是⊥
,对于一些原因,所以不存在用于实际的符号⊥
在Haskell代码3。 zip [] _|_ = []
是属性的文档,它是zip
定义的结果,而不是其定义的一部分。
作为对这个属性的描述zip [] _ = []
是一个不太具体的声明; 它会说无论你调用什么zip []
,它都会返回[]
。 它相当于完全相同的东西,因为zip [] ⊥
可以返回非底部的唯一方法是它根本不检查它的第二个参数。 但它对非严格性的定义没有那么直接。
由于构成函数zip [] _ = []
定义的一部分的代码无法与zip [] _|_ = []
进行比较和对比。 它们不是替代品,第一个是有效代码,第二个不是。
1这是永远运行、抛出异常或以其他方式计算为正常值的表达式的“值”。
2它甚至不是有效的 Haskell 标识符,因为它同时包含“namey”字符 ( _
) 和“operator”字符 ( |
)。 所以它实际上不能是 Haskell 代码中任何意义的符号!
3 undefined
通常用于⊥
,但它更像是一个引用⊥
值的变量,而不是实际事物本身。 就像如果你有let xs = [1, 2, 3]
你可以使用xs
来引用列表[1, 2, 3]
,但你不能将它用作匹配其他列表的模式; 尝试的模式匹配将被视为引入一个名为undefined
的新变量或xs
隐藏旧变量。
⊥ 出自数理序理论。 一个部分有序的集合有一个底部元素,表示为 ⊥,如果该元素在所有其他元素之前。 这如何进入 Haskell 文档? 在某个时候,计算机科学家意识到考虑计算机程序(无论使用何种语言)“意味着”是有用的。 一种方法称为指称语义。 在指称语义中,编程语言中的每个术语都被分配了一个“指称”或含义,在某些数学含义领域。 例如,如果能够说
meaningInteger :: Integer -> mathematical integer
meaningList :: [a] -> possibly-infinite sequence of elements of type a
不幸的是,这在 Haskell 中不太适用,因为例如,我可以写
oops :: Integer
oops = oops
这给了我一个Integer
类型的术语,但没有合理的方法将其指定为数学整数的含义。 更有趣的是,我可以写这样的东西
undefined
undefined : undefined
3 : undefined
[undefined]
let foo = undefined : 3 : undefined : foo
这些都(可以)具有相同的类型,但具有各种不同级别的不确定性。 因此,我们需要将各种未定义的事物添加到我们的含义集合中。 但是,可以根据它们的定义对它们施加偏序! 例如3 : 4 : []
比3 : 4 : undefined
更3 : 4 : undefined
,也比3 : undefined : 4
更明确,但后两者没有可比性。 每种类型的底部元素,其定义最少的元素,称为 ⊥。
对 AJFarmar 的回答嗤之以鼻,我认为这个关键点没有明确说明:
_|_
在 Haskell 代码中不是有效的文字或标识符!zip [] _|_ = []
也不是有效代码!这隐含在 AJFarmar 这句话的意思中:
[T]他行
zip [] _|_ = []
不充当模式匹配,而是一个等式,说明zip [] _|_
和[]
的相等性。
为了使它非常清晰, zip [] _|_ = []
出现在zip
定义的文档注释中。 它不是 Haskell 代码——它是用非正式的技术符号编写的英语注释,看起来有点像 Haskell 代码。 或者,换句话说,伪代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.