为什么ghc给我一个“1 ++ 2”而不是愤怒退出的类型?

时间:2013-02-23 14:28:04

标签: haskell

GHCI将为我提供1 ++ 2的类型:

$ ghci
GHCi, version 7.4.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :t 1 ++ 2
1 ++ 2 :: Num [a] => [a]

但这显然是错误的。如果我尝试评估它,而不是只是键入检查它,事情就会失败:

Prelude> 1 ++ 2

<interactive>:3:1:
    No instance for (Num [a0])
      arising from the literal `1'
    Possible fix: add an instance declaration for (Num [a0])
    In the first argument of `(++)', namely `1'
    In the expression: 1 ++ 2
    In an equation for `it': it = 1 ++ 2

是什么给出了?

2 个答案:

答案 0 :(得分:25)

  

但这显然是错误的。

不,这是完全正确的。

(++)的类型是

(++) :: [a] -> [a] -> [a]

和整数文字的类型是

1 :: Num n => n

因此,[a]的参数必须具有的(++)类型与文字所具有的类型Num n => n统一,给出

1 ++ 2 :: Num [a] => [a]

如果您有一个带有Num实例的列表类型,那么也可以评估该表达式。

但是,默认情况下,可用的列表类型没有Num实例,因此当您尝试评估它时,ghci会抱怨它找不到Num的{​​{1}}实例。< / p>

例如:

[a]

答案 1 :(得分:16)

因为有人可以定义要被视为数字的列表:

instance Num a => Num [a] where
 (+) = zipWith (+)
 (*) = zipWith (*)
 (-) = zipWith (-)
 negate = map negate
 abs = map abs
 signum = map signum
 fromInteger x = [fromInteger x]

然后你键入的内容将起作用,因为

  1++2 == fromInteger 1++fromInteger 2 == [1]++[2]

(不是说这个Num实例会有意义..)