卡尔的答案很好。这是我认为没有其他人提到的其他用途。的类型
if E then A else B
应该是一种类型,其中包含类型为的A
所有值和类型为的所有值B
。如果类型B
为Nothing
,则if
表达式的类型可以为类型A
。我会经常声明一个例程
def unreachable( s:String ) : Nothing = throw new AssertionError("Unreachable "+s)
表示无法达到代码。由于其类型为Nothing
,unreachable(s)
因此现在可以在不影响结果类型的情况下以任何方式if
(或更频繁地)switch
使用。例如
val colour : Colour := switch state of
BLACK_TO_MOVE: BLACK
WHITE_TO_MOVE: WHITE
default: unreachable("Bad state")
Scala具有这种Nothing类型。
另一个用例Nothing
(如卡尔的回答中所述)是List [Nothing],即列表的类型,其成员的类型均为Nothing。因此,它可以是空列表的类型。
Nothing
使这些用例起作用的关键特性不是它没有值-尽管在Scala中,它没有值-而是它是所有其他类型的子类型。
假设您有一种语言,其中每种类型都包含相同的值-称之为它()
。用这种语言,具有()
唯一价值的单位类型可以是每种类型的子类型。从OP的意义上来说,这并不能使其成为底层类型。OP很清楚,底部类型不包含任何值。但是,由于它是每个类型的子类型,因此它可以与底部类型扮演几乎相同的角色。
Haskell的处理方式有所不同。在Haskell中,从不产生值的表达式可以具有scheme类型forall a.a
。这种类型方案的实例将与任何其他类型统一,因此即使(标准)Haskell没有子类型的概念,它也可以有效地作为底部类型。例如,error
标准序言中的函数具有type scheme forall a. [Char] -> a
。所以你可以写
if E then A else error ""
A
对于任何表达式,表达式的类型将与的类型相同A
。
Haskell中的空列表具有类型方案forall a. [a]
。如果A
是类型为列表类型的表达式,则
if E then A else []
是与类型相同的表达式A
。
void
数据...