Question

Novice question. Let's say that I've created a simple list typeclass that takes two strings and adds their respective elements if they're integers or concatenates them if they're strings:

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]

This compiles, but if I run addLists [1,2,3] [1,2,3] in GHCi I get the error

<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]

Adding :: [Int] to the expression allows it to be evaluated, but I don't understand why the error appears in the first place.

Was it helpful?

Solution

Because the default for integral literal numbers is Integer, and not Int:

4.3.4 Ambiguous Types, and Defaults for Overloaded Numeric Operations

[...]

Only one default declaration is permitted per module, and its effect is limited to that module. If no default declaration is given in a module then it assumed to be:

  default (Integer, Double) 

Note that you can fix this easily if you change the type of addNumLists and add the Integer instance:

-- 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 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top