Haskell列表类型错误列表

Haskell List of List Type Error

在 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 是一种静态类型语言,因此任何类型错误都应该在编译时捕获。我想知道为什么以上两个错误在不同的时间被捕获?

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

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

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

见ma,没有错误!