Haskell中什么都没有?

时间:2014-02-27 10:16:14

标签: haskell types

我在“为了好大学而学习你的哈斯克尔”一书的第118页。

写在那里:

ghci> :t Nothing 
Nothing :: Maybe a

这是我的问题:

如果我理解正确,Nothing是一个值,只有具体类型可以有值,但Maybe a不是具体类型。那么它如何具有值Nothing

这本书还说:

  

请注意,Nothing的类型可能是a。它的类型是多态的。

多态类型是什么意思?我该怎么理解这个?这与仅具体类型可以具有价值的规则不矛盾吗?

编辑:

从本书的PDF版本:

  

如果不采用任何类型参数,我们说类型是具体的   在所有(如Int或Bool),或者如果它采用类型参数,他们是   所有人都填满了(比如Maybe Char)。如果你有一些价值,它的类型是   总是具体的类型。

5 个答案:

答案 0 :(得分:13)

这并不矛盾。 Nothing是一个值,其具体类型可能是Maybe a的任何可能的实例化。

否则说,类型Maybe a的值继续具有具体类型Maybe IntMaybe StringMaybe Whatever,特别是Nothing能够由每个人输入,具体取决于具体情况。这是因为它的构造函数(再次称为Nothing :: Maybe a)不接受任何参数,因此可以按原样调用它来生成类型Maybe a的值。如果您愿意,我们将根据具体类型提供一种。

如果没有上下文,ghci当然会为你提供Nothing可以推断出的最一般的类型,即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中不起作用数)。

答案 1 :(得分:5)

  

这与规则不矛盾,唯一的具体类型可以有价值吗?

由于函数是Haskell中的第一类值,因此这个声称的规则意味着诸如mapfoldr之类的多态函数将无法实现。

事实上,Haskell中有很多多态非函数值,例如

1 :: Num a => a
Nothing :: Maybe a
[] :: [a]
Left 1 :: Num a => Either a b

等。这些值适用于a(和b)的每个实例化。

答案 2 :(得分:3)

从某种意义上说,你是对的。没有forall a.Maybe a类型的值。你构造的每个Maybe值实际上都有一些明确的类型Maybe tau,其中tau可能是已知的,但是它是一些明确的类型。

符号Nothing :: forall a.Maybe a只是告诉我们,每当我们使用表达式Nothing时,它都会构造一个预期Maybe类型的值。

答案 3 :(得分:1)

Maybe类型有两个构造函数:Nothing和Just a,其中a是一个类型变量。没有什么本身不会决定(约束)类型,但在任​​何合理的上下文中你都会发现类似的东西(我并不认为它在语法上是正确的Haskell,而是10年前我会写的):

if (foo == 5)
then Nothing
else Just 5

然后类型推断会告诉你(假设5是这个类型为Int的代码片段'foo'的参数)foo有类型:

foo :: Int -> Maybe Int

但正如之前的海报所指出的,也许a是一种非常好的类型。您将找到与[]相同的非问题,即带有[]的列表类型(空列表的构造函数)。

答案 4 :(得分:0)

This在26:00谈话回答了问题:“[ ]的类型是什么?”这是“Nothing的类型是什么的相关问题。”

Hudak的书也有一个很好的段落:

enter image description here