26

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

是什么赋予了?

4

2 回答 2

25

但这显然是错误的。

不,完全正确。

的类型(++)

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

整数文字的类型是

1 :: Num n => n

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

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

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

但是,默认情况下,没有可用的列表类型的实例Num,因此当您尝试评估它时,ghci 抱怨它找不到.Num[a]

例如:

Prelude> instance Num a => Num [a] where fromInteger n = Data.List.genericReplicate n 1 

<interactive>:2:10: Warning:
    No explicit method or default declaration for `+'
    In the instance declaration for `Num [a]'

<interactive>:2:10: Warning:
    No explicit method or default declaration for `*'
    In the instance declaration for `Num [a]'

<interactive>:2:10: Warning:
    No explicit method or default declaration for `abs'
    In the instance declaration for `Num [a]'

<interactive>:2:10: Warning:
    No explicit method or default declaration for `signum'
    In the instance declaration for `Num [a]'
Prelude> 1 ++ 2 :: [Int]
[1,1,1]
于 2013-02-23T14:32:52.843 回答
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例子很有意义..)

于 2013-02-23T15:54:42.323 回答