根据这个关于Haskell的指称语义的article,从Int到Int只有一个非严格(非底部保留)函数。
引用:
碰巧只有一个Integer类型的非严格函数的原型 - >整数:
一个x = 1
对于每个具体数字k,其变体是constk x = k。为什么这些是唯一可能的?请记住,一个n可以不少于定义,而不是一个。由于Integer是一个扁平域,因此两者必须相等。
基本上它表示该类型签名的唯一非严格函数只能是常量函数。我不遵循这个论点。我也不确定扁平域是什么意思,文章的其余部分让我们相信它只是意味着值的poset只有一个节点:bottom。
对于从A-> A或A-> B的功能发生类似的事情?那就是它们必须是常数函数吗?
答案 0 :(得分:16)
Integer
上某个常量const k
不是k
的任何函数都必须检查其参数。您无法部分检查Integer
,其中可能是是“平面域”的含义。这是Haskell规范中定义Integer
的语义的结果,而不是核心语言的语义。
相比之下,每种类型[a] -> [a]
都存在无数种类型为a
的非严格函数,例如take1
:
take1 (x:_) = [x]
要显示非严格性,请定义
ones = 1 : ones
在指称语义方面,[[ones
]] =⊥。但take1 ones
评估为[1]
,因此take1
不严格。 take2 (x:y:_) = [x,y]
,take10
等
如果你想在整数上使用非严格的非常数函数,你需要一个不同于Integer
的整数表示,例如:
data Bit = Zero | One
newtype BinaryInt = I [Bit]
如果我们将I
中的列表解释为“little-endian”二进制整数,那么函数
mod2 (I []) = I []
mod2 (I (lsb:_)) = I [lsb]
是非严格的。
答案 1 :(得分:15)
直觉是懒惰的函数不能在不强制它的情况下检查它的参数(因此变得严格)。如果你不检查你的论点,你必须是const
单调性的真正答案。如果您将语义域视为其中排序关系是“已定义”之一的posets,则所有函数都是顺序保留。为什么?由于所有底部都是相同的,并且永远循环与底部相同,因此非单调函数将解决停止问题。
好的,那么为什么这意味着它const
会创建唯一的惰性函数?好吧,说选择一个任意函数f
,这样
f :: Integer -> Integer
f ⊥ = y
所有⊥ <= x
的{{1}},必须是x
。如果y <= f x
是非底值,那么该不等式的唯一解决方案是y
编辑:此参数适用于f x = y
和Integer
等类型但不适用于Bool
类型的原因是最后一步:[a]
在某种意义上只有其中只有一个Integer
。也就是说,除了⊥
之外,所有整数都是同等定义的。另一方面,⊥
⊥ < (⊥:⊥)
和(⊥:⊥) < (⊥:[])
更多,(⊥:⊥) < (⊥:(⊥:⊥)) < (⊥:(⊥:(⊥:⊥))) < ...
。也就是说,(⊥:⊥) < ('a':⊥)
的语义域足够丰富,[a]
y <= f x
并不意味着y =/= ⊥
。