3

我最近开始潜入 Haskell。它很有趣,但它的定义Nothing让我感到困惑,并没有陷入困境。关于 GHCI

Prelude> :t Nothing
Nothing :: Maybe a

Nothing应该Just Nothing,为什么Maybe a

4

4 回答 4

19

这是Maybe类型的定义:

data Maybe a = Nothing | Just a

这表明对于某些类型a,该类型Maybe a有两个构造函数:NothingJust a(是应用于 LHSa的相同类型变量)。Maybe

希望很清楚Just "foo"has typeMaybe StringJust '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

于 2012-03-27T11:39:27.430 回答
6

Maybe被定义为

data Maybe a = Nothing | Just a

对于 allNothing类型的(无参数)值构造函数也是如此,并且它表示的值可以属于所有类型,无论是它们,还是被实例化的任何东西。Maybe aaMaybe aMaybe BoolMaybe [IO (Int,Char)]a

于 2012-03-27T11:38:56.277 回答
4

Maybe定义为

data Maybe a = Nothing | Just a

所以它可以是NothingJust aMayba a是类型,Nothing并且Just a是值构造函数。Just Nothing将是一个可能包裹在一个可能中,即Maybe (Maybe a).

于 2012-03-27T11:39:17.977 回答
1

考虑具有子类型的 Scala。其等价于Nothing称为NoneNone有 type None,它是 的子类型Option[a]Scala 等价于Justis Some(foo),它有 type Some[Foo]Option[Foo]. Haskell 没有子类型,因此将它们都键入为它们共同的超类型,因为这对它们来说是最有用的类型。

于 2012-03-27T17:18:54.030 回答