这并不矛盾。 Nothing
是一个值,其具体类型可以是Maybe a
的任何可能实例。
换句话说,Maybe a
类型的值继续具有具体类型Maybe Int
、Maybe String
、Maybe Whatever
,特别地,取决于上下文,Nothing
能够被它们中的每一个类型赋值。因为它的构造函数,也称为Nothing :: Maybe a
,不需要任何参数,因此可以直接调用以生成Maybe a
类型的值。如果您愿意,对于每种具体类型,我们将会有一个这样的值。
当然,在没有上下文的情况下,ghci会给出它可以推导出的最通用类型Maybe a
,但这不是它的具体类型,这将取决于您将在其中使用Nothing
的个别表达式。例如:
ghci> Nothing
Nothing
it :: Maybe a
这可能是您键入的内容,或类似于此的内容。由于没有进一步的上下文,因此 Nothing
不会以具体类型键入。
ghci> Nothing :: Maybe Int
Nothing
it :: Maybe Int
在这里,我强制它假定具体类型为Maybe Int
。
ghci> 1 + fromMaybe 2 Nothing
3
it :: Integer
如果我将它与一些整数相加(fromMaybe :: a -> Maybe a -> a
接受默认值和 Maybe a
并返回 Just
中的值或 Nothing
的默认值), 那么系统将把 Nothing
归类为 Maybe Integer
,因为您希望从中提取一个整数。但是这里没有整数,所以在这种情况下,我们将 1 与默认值 2 相加。
ghci> 1 + fromMaybe 2 (Nothing :: Maybe Integer)
3
it :: Integer
我也是这样做的,为了进行二次检查。我们强制Nothing
在同一个表达式中具有我们先前假定的具体类型。
ghci> 1 + fromMaybe 2 (Nothing :: Maybe Char)
<interactive>:1:15:
No instance for (Num Char)
arising from the literal `2'
Possible fix: add an instance declaration for (Num Char)
In the first argument of `fromMaybe', namely `2'
In the second argument of `(+)', namely
`fromMaybe 2 (Nothing :: Maybe Char)'
In the expression: 1 + fromMaybe 2 (Nothing :: Maybe Char)
为了三次检查,如果我们强制它假设另一种具体类型,你会发现它的值完全不同,导致类型错误(与C不同,在Haskell中,Char
不作为数字)。
a
,"Maybe a" 都是一个具体类型。对于任何a
,"Nothing" 都是 "Maybe a" 的一种值。 - Sassa NF*
的类型。这似乎是导致所有混淆的原因。根据该书的定义,Maybe a
是具体类型,而仅有的Maybe
则不是。因此,Nothing
是Maybe a
类型绝对没有问题。话虽如此,“具体”并不是官方术语,每个人使用它的方式也都不同。 - kosmikus