Haskell列表类型错误列表

Che*_*ish 5 haskell types ghci

在GHCi中,我输入

let xs = [1, 'a']
Run Code Online (Sandbox Code Playgroud)

它会立即抱怨错误:

<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']
Run Code Online (Sandbox Code Playgroud)

但是,当我输入

let xs = [1, [1, 1]]
Run Code Online (Sandbox Code Playgroud)

它刚刚过去了.当我尝试打印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
Run Code Online (Sandbox Code Playgroud)

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

Dan*_*ner 8

1是类型的多态值Num 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
Run Code Online (Sandbox Code Playgroud)

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

> let xs = [1, [1, 1]]
> xs
[[1],[1,1]]
Run Code Online (Sandbox Code Playgroud)

看马,没错!

  • 为什么同样的推理不适用于潜在的"Num Char"实例呢? (3认同)