Haskell列表类型错误列表

时间:2015-06-04 23:33:24

标签: haskell types ghci

在GHCi中,我输入

let xs = [1, 'a']

它立即抱怨错误:

<interactive>:28:11:
No instance for (Num Char) arising from the literal ‘1’
In the expression: 1
In the expression: [1, 'a']
In an equation for ‘xs’: xs = [1, 'a']

然而,当我输入

let xs = [1, [1, 1]]

它刚过去了。当我尝试打印xs时,它会抱怨:

<interactive>:5:1:
No instance for (Num [t0]) arising from a use of ‘it’
In a stmt of an interactive GHCi command: print it

我认为Haskell是一种静态类型语言,因此任何类型错误都应该在编译时捕获。我想知道为什么在不同时间捕获上述2个错误?

1 个答案:

答案 0 :(得分:8)

1Num a => a类型的多态值。所以在[1, [2, 3]]中,我们有[2, 3] :: Num a => [a];由于所有列表元素必须具有相同的类型,因此我们得出结论:我们必须具有1 :: Num a => [a]。这有点奇怪 - 将1视为具有列表类型是奇怪的 - 但如果有人创建了一个足够奇怪的Num实例,则可以完全有效。在您尝试使用实例之前,将检查是否存在实例;这使您有机会在使用实例定义值后定义实例。因此,在您尝试使用列表[1, [2, 3]]实际执行某些操作之前,它不会抱怨。

为了说明我的意思,可以写一下:

instance Num a => Num [a] where
    fromInteger n = pure (fromInteger n)
    (+) = liftA2 (+)
    (-) = liftA2 (-)
    (*) = liftA2 (*)
    abs    = liftA abs
    signum = liftA signum

(事实上,这个实例适用于任何Applicative,偶尔也会有用。)然后,在ghci:

> let xs = [1, [1, 1]]
> xs
[[1],[1,1]]

见ma,没有错误!