Haskell 中的 undefined 和 Java 中的 null 有什么区别?

2024-04-12

两者的类型都是所有类型的交集(无人居住)。两者都可以在代码中传递而不会失败,直到尝试评估它们为止。我能看到的唯一区别是,在 Java 中,有一个漏洞允许null仅针对一个操作进行评估,即引用相等比较(==)--而在 Haskell 中undefined根本无法在不引发异常的情况下进行评估。这是唯一的区别吗?

Edit

我真正想回答这个问题的是,为什么要包括null在 Java 中这样一个显然是错误的决定,Haskell 如何避免它呢?在我看来,真正的问题是你能做点什么useful with null,即你可以检查它nullness。因为您可以这样做,所以在代码中传递空值并让它们指示“无结果”而不是“此程序中存在逻辑错误”已成为标准约定。而在 Haskell 中,没有办法在不评估术语和程序爆炸的情况下检查术语是否评估为底部,因此它永远不能以这种方式使用来指示“无结果”。相反,人们被迫使用类似的东西Maybe.

抱歉,如果我似乎对“评估”这个词玩得太快了……我试图在这里打一个类比,但很难准确地表达它。我想这表明这个类比不准确。


Haskell 中的 undefined 和 Java 中的 null 有什么区别?

好吧,让我们稍微备份一下。

Haskell 中的“未定义”是“底部”值(表示为 ⊥)的一个示例。这样的值表示程序中任何未定义、卡住或部分状态。

存在许多不同形式的底层:非终止循环、异常、模式匹配失败——基本上是程序中在某种意义上未定义的任何状态。价值undefined :: a是将程序置于未定义状态的值的典型示例。

undefined本身并不是特别特别——它没有连接——你可以实现 Haskell 的undefined使用任何底部产生的表达式。例如。这是一个有效的实现undefined:

 > undefined = undefined

或者立即退出(旧的Gofer编译器使用这个定义):

 > undefined | False = undefined

底部的主要属性是,如果表达式计算结果为底部,则整个程序将计算为底部:程序处于未定义状态。

为什么你想要这样的值?好吧,在惰性语言中,您通常可以操作存储底部值的结构或函数,而程序本身并不位于底部。

例如。无限循环列表是完美的:

 > let xs = [ let f = f in f 
            , let g n = g (n+1) in g 0
            ]
 > :t xs
 xs :: [t]
 > length xs
 2

我对列表中的元素无能为力:

 > head xs
 ^CInterrupted.

这种对无限事物的操纵是 Haskell 如此有趣和富有表现力的部分原因。懒惰的结果是 Haskell 尤为关注的bottom values.

然而,显然,底层的概念同样适用于 Java 或任何(非总体)语言。在 Java 中,有许多表达式可以产生“底部”值:

  • 将引用与 null 进行比较(但请注意,不是null本身,这是明确定义的);
  • 被零除;
  • 越界异常;
  • 无限循环等

您只是无法轻松地将一个底部替换为另一个底部,并且 Java 编译器不会对底部值进行太多推理。然而,这样的价值观是存在的。

总之,

  • 解除引用anullJava 中的 value 是一种在 Java 中产生底部值的特定表达式;
  • the undefinedHaskell 中的 value 是一个通用的底部产生表达式,可以在 Haskell 中需要底部值的任何地方使用。

这就是他们的相似之处。

后记

至于问题null本身:为什么它被认为是不好的形式?

  • 首先,Java的null本质上相当于添加隐式Maybe a每种类型a在哈斯克尔.
  • 解引用null相当于仅针对Just case: f (Just a) = ... a ...

所以当传入的值为Nothing(在哈斯克尔),或null(在 Java 中),您的程序达到未定义状态。这很糟糕:你的程序崩溃了。

所以,通过添加null to every类型,您刚刚使创建变得更加容易bottom意外的值——类型不再对你有帮助。您的语言不再帮助您防止这种特定类型的错误,这很糟糕。

当然,其他底部值仍然存在:例外(例如undefined) ,或无限循环。为每个函数添加新的可能的故障模式——取消引用null——只是让编写崩溃的程序变得更容易。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell 中的 undefined 和 Java 中的 null 有什么区别? 的相关文章

随机推荐