Haskell 语言在引用透明度方面提供的精确 promise /保证是什么?至少 Haskell 报告没有提到这个概念。
考虑表达式
(7^7^7`mod`5`mod`2)
我想知道这个表达式是否为1。为了我的安全,我会执行两次:
( (7^7^7`mod`5`mod`2)==1, [False,True]!!(7^7^7`mod`5`mod`2) )
现在使用 GHCi 7.4.1 给出 (True,False)
。
显然,这个表达式现在是引用不透明的。我如何判断程序是否存在此类行为?我可以用 ::
淹没整个程序,但这并不会使它变得非常可读。中间还有其他我想念的 Haskell 程序吗?那是介于完全注释和未注释之间吗?
(除了我在SO上发现的唯一的related question之外,一定还有其他东西)
最佳答案
对于“兼容”的任何合理定义,我认为无法保证以不同类型评估多态类型表达式(例如 5
)会产生“兼容”结果。
GHCi session :
> class C a where num :: a
> instance C Int where num = 0
> instance C Double where num = 1
> num + length [] -- length returns an Int
0
> num + 0 -- GHCi defaults to Double for some reason
1.0
这看起来破坏了引用透明度,因为 length []
和 0
应该相等,但在幕后,它正在使用 num
不同类型。
另外,
> "" == []
True
> [] == [1]
False
> "" == [1]
*** Type error
人们可能期望最后一行出现False
。
因此,我认为引用透明度仅在指定确切类型来解决多态性时才有效。 System F 中的显式类型参数应用程序可以始终用变量的定义替换变量,而不改变语义:据我了解,GHC 在优化过程中内部正是这样做的,以确保语义不受影响。事实上,GHC Core 具有可传递的显式类型参数。
关于haskell - 类型推断会干扰引用透明度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27019906/