我最近开始潜入 Haskell。它很有趣,但它的定义Nothing
让我感到困惑,并没有陷入困境。关于 GHCI
Prelude> :t Nothing
Nothing :: Maybe a
不Nothing
应该Just Nothing
,为什么Maybe a
?
这是Maybe
类型的定义:
data Maybe a = Nothing | Just a
这表明对于某些类型a
,该类型Maybe a
有两个构造函数:Nothing
和Just a
(是应用于 LHSa
的相同类型变量)。Maybe
希望很清楚Just "foo"
has typeMaybe String
和Just 'c'
has type Maybe Char
。但是什么类型Nothing
?由于Nothing
不包含任何值,它的构造函数不使用a
类型变量,因此没有任何东西可以将其类型限制为Maybe
.
这使它成为“多态常数”。Nothing
可以在Maybe
预期任何类型的上下文中使用,因为它在所有类型中都同样有效。这就是为什么 GHCi 将其类型报告为简单的原因Maybe a
:thea
是一个可以表示任何类型的变量,它所指的类型将由基于使用该Nothing
值的上下文的推断来确定。但是当你自己给出时Nothing
,并没有关于它的具体类型的额外线索,所以你只是看到了变量。
> :t Nothing
Nothing :: Maybe a
> :t (Nothing :: Maybe Int)
(Nothing :: Maybe Int) :: Maybe Int
> :t (Nothing :: Maybe Char)
(Nothing :: Maybe Char) :: Maybe Char
顺便说一句,Just Nothing :: Maybe (Maybe a)
; 这是一个Maybe
包裹在另一个Maybe
。
Maybe
被定义为
data Maybe a = Nothing | Just a
对于 allNothing
类型的(无参数)值构造函数也是如此,并且它表示的值可以属于所有类型,无论是它们,还是被实例化的任何东西。Maybe a
a
Maybe a
Maybe Bool
Maybe [IO (Int,Char)]
a
Maybe
定义为
data Maybe a = Nothing | Just a
所以它可以是Nothing
或Just a
。Mayba a
是类型,Nothing
并且Just a
是值构造函数。Just Nothing
将是一个可能包裹在一个可能中,即Maybe (Maybe a)
.
考虑具有子类型的 Scala。其等价于Nothing
称为None
。None
有 type None
,它是 的子类型。Option[a]
Scala 等价于Just
is Some(foo)
,它有 type Some[Foo]
,它是Option[Foo]
. Haskell 没有子类型,因此将它们都键入为它们共同的超类型,因为这对它们来说是最有用的类型。