haskell - 类型推断会干扰引用透明度

标签 haskell referential-transparency adhoc-polymorphism

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/

相关文章:

scala - 类型类接口(interface)的DataSet/DataStream

haskell - Stack 的 package.yaml 的默认构建选项有何用途?

haskell - 我如何递归地用 “%20"替换字符串中的空格?

haskell - 如何不纯地修改与对象关联的状态?

haskell - "inject"Haskell 计算中的进度记录/跟踪?

haskell - 1 :1 type/type-class-instance relation? 是否有可行且类型安全的替代方案

haskell - 堆栈如何解决依赖关系?

optimization - Foldl 是尾递归,那么为什么foldr 运行得比foldl 快呢?

java - 是否有处理器/插件可以在 Java 中强制执行引用透明、不可变等?

rust - 这个理解对吗: trait and function overloading both achieved ad hoc polymorphism but in different direction