我在"为了好大学而学习你的哈斯克尔"一书的第118页.
它写在那里:
ghci> :t Nothing
Nothing :: Maybe a
Run Code Online (Sandbox Code Playgroud)
这是我的问题:
如果我理解正确,Nothing是一个值,只有具体类型可以有值,但Maybe a不是具体类型.那怎么能有价值Nothing呢?
书中还说:
请注意,Nothing的类型可能是a.它的类型是多态的.
多态类型是什么意思?我该怎么理解这个?这与仅具体类型可以具有价值的规则不矛盾吗?
编辑:
从本书的PDF版本:
我们说如果一个类型根本不采用任何类型参数(如Int或Bool),或者如果它采用类型参数并且它们都被填满(如Maybe Char),那么它是具体的.如果你有一些价值,它的类型总是具体的类型.
Ric*_* T. 13
这并不矛盾.Nothing是一个值,其具体类型可以是任何可能的实例化Maybe a.
否则说,类型的值Maybe a继续有具体的类型Maybe Int,Maybe String,Maybe Whatever,特别是,Nothing能够通过他们每个人的键入,根据上下文.那是因为它的构造函数再次被调用Nothing :: Maybe a,它不接受任何参数,因此可以按原样调用它来生成类型的值Maybe a.如果您愿意,我们将根据具体类型提供一种.
如果没有上下文,当然ghci的会给你最普遍的类型,可以推断Nothing,这是Maybe a,但它不是它的具体类型.这将取决于您将使用的各个表达式Nothing.例如:
ghci> Nothing
Nothing
it :: Maybe a
Run Code Online (Sandbox Code Playgroud)
这是你可能输入的东西,或类似的东西.没有进一步的上下文,因此Nothing不会输入具体类型.
ghci> Nothing :: Maybe Int
Nothing
it :: Maybe Int
Run Code Online (Sandbox Code Playgroud)
在这里,我强迫它承担具体类型Maybe Int.
ghci> 1 + fromMaybe 2 Nothing
3
it :: Integer
Run Code Online (Sandbox Code Playgroud)
如果我将它与一个整数之和混合(fromMaybe :: a -> Maybe a -> a取一个默认值和一个Maybe a并返回默认值Just或默认值Nothing),那么Nothing将由Maybe Integer系统输入,因为你希望从中提取一个整数.没有,所以在这种情况下,我们将1与默认值2相加.
ghci> 1 + fromMaybe 2 (Nothing :: Maybe Integer)
3
it :: Integer
Run Code Online (Sandbox Code Playgroud)
同样在这里,仔细检查.我们强迫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)
Run Code Online (Sandbox Code Playgroud)
要进行三重检查,如果我们强制它采用另一种具体类型,正如您所看到的那样,它的值将完全不同,从而导致类型错误(与C不同,在Haskell Char中不作为数字).
这与规则不矛盾,唯一的具体类型可以具有价值吗?
由于函数是Haskell中的第一类值,因此这个声称的规则意味着多态函数,例如map和foldr将无法实现.
事实上,Haskell中有很多多态非函数值,例如
1 :: Num a => a
Nothing :: Maybe a
[] :: [a]
Left 1 :: Num a => Either a b
Run Code Online (Sandbox Code Playgroud)
这些值存在于a(和b)的每个实例中.