类实例中的模糊变量

pla*_*ian 3 haskell typeclass

新手问题.假设我创建了一个简单的列表类型类,它接受两个字符串,如果它们是整数则添加它们各自的元素,如果它们是字符串则连接它们:

class NewList a where
    addLists :: [a] -> [a] -> [a]

instance NewList Int where
    addLists = addNumLists 

addNumLists :: [Int] -> [Int] -> [Int]
addNumLists (x : xs) (y : ys) = x + y : addNumLists xs ys
addNumLists _ _ = []

instance NewList Char where
    addLists x y = concat [x,y]
Run Code Online (Sandbox Code Playgroud)

这编译,但如果我addLists [1,2,3] [1,2,3]在GHCi中运行,我得到错误

<interactive>:278:11:
Ambiguous type variable `a0' in the constraints:
  (Num a0) arising from the literal `1' at <interactive>:278:11
  (NewList a0)
    arising from a use of `addLists' at <interactive>:278:1-8
Probable fix: add a type signature that fixes these type variable(s)
In the expression: 1
In the first argument of `addLists', namely `[1, 2, 3]'
In the expression: addLists [1, 2, 3] [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

添加:: [Int]到表达式允许对其进行评估,但我不明白为什么错误首先出现.

Zet*_*eta 7

因为整数文字数字的默认Integer,而不是Int:

4.3.4模糊类型和重载数值运算的默认值

[...]

每个模块只允许一个默认声明,其效果仅限于该模块.如果模块中没有给出默认声明,则假定它是:

  default (Integer, Double) 
Run Code Online (Sandbox Code Playgroud)

请注意,如果更改类型addNumLists并添加Integer实例,则可以轻松解决此问题:

-- We don't need `Int`, we only need `+`, so anything that is `Num` should work
addNumLists :: (Num a) => [a] -> [a] -> [a]
addNumLists (x : xs) (y : ys) = x + y : addNumLists xs ys
addNumLists _ _ = []

instance NewList Integer where
    addLists = addNumLists 
Run Code Online (Sandbox Code Playgroud)