我最近开始潜入Haskell。它非常有趣,但Nothing
的定义让我感到困惑,并没有陷入其中。在GHCI上
Prelude> :t Nothing
Nothing :: Maybe a
不应Nothing
为Just Nothing
,为什么Maybe a
?
答案 0 :(得分:19)
以下是Maybe
类型的定义:
data Maybe a = Nothing | Just a
这表明对于某些类型a
,类型Maybe a
有两个构造函数:Nothing
和Just a
(a
是Maybe
相同的类型变量{ {1}}适用于LHS)。
希望明确Just "foo"
类Maybe String
和Just 'c'
类型Maybe Char
的方式很清楚。但是Nothing
是什么类型的?由于Nothing
不包含任何值,因此其构造函数不使用a
类型变量,因此没有任何内容将其类型约束为特定形式的Maybe
。
这使它成为“多态常数”。 Nothing
可以在期望任何Maybe
类型的上下文中使用,因为它在所有类型中都同样有效。这就是GHCi将其类型简单地报告为Maybe a
的原因:a
是一个可以表示任何类型的变量,它所引用的类型将基于{{1的上下文的推理来确定使用了值。但是当你自己提供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
。
答案 1 :(得分:6)
Maybe
已定义
data Maybe a = Nothing | Just a
所以Nothing
是Maybe a
类型的(无参数)值构造函数,对于所有a
,它表示的值可以属于所有类型Maybe a
,是他们Maybe Bool
,Maybe [IO (Int,Char)]
或其他a
实例化了。
答案 2 :(得分:4)
Maybe
定义为
data Maybe a = Nothing | Just a
因此它可以是Nothing
或Just a
。 Mayba a
是类型,Nothing
和Just a
是值构造函数。 Just Nothing
可能包含在一个可能的内容中,即Maybe (Maybe a)
。
答案 3 :(得分:1)
考虑Scala,它有子类型。它等同于Nothing
,称为None
。 None
的类型为None
,是Option[a]
的子类型。与Just
等效的Scala是Some(foo)
,其类型为Some[Foo]
,是Option[Foo]
的子类型。 Haskell没有子类型,因此将它们都作为常用的超类型键入,因为这是对它们最有用的类型。