为什么从Int到Int只有一个非严格的函数?

时间:2013-01-10 16:01:18

标签: haskell functional-programming computer-science

根据这个关于Haskell的指称语义的article,从Int到Int只有一个非严格(非底部保留)函数。

引用:

  

碰巧只有一个Integer类型的非严格函数的原型 - >整数:

     

一个x = 1

     

对于每个具体数字k,其变体是constk x = k。为什么这些是唯一可能的?请记住,一个n可以不少于定义,而不是一个。由于Integer是一个扁平域,因此两者必须相等。

基本上它表示该类型签名的唯一非严格函数只能是常量函数。我不遵循这个论点。我也不确定扁平域是什么意思,文章的其余部分让我们相信它只是意味着值的poset只有一个节点:bottom。

对于从A-> A或A-> B的功能发生类似的事情?那就是它们必须是常数函数吗?

2 个答案:

答案 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 = yInteger等类型但不适用于Bool类型的原因是最后一步:[a]在某种意义上只有其中只有一个Integer。也就是说,除了之外,所有整数都是同等定义的。另一方面, ⊥ < (⊥:⊥)(⊥:⊥) < (⊥:[])更多,(⊥:⊥) < (⊥:(⊥:⊥)) < (⊥:(⊥:(⊥:⊥))) < ...。也就是说,(⊥:⊥) < ('a':⊥)的语义域足够丰富,[a] y <= f x并不意味着y =/= ⊥