Reputation: 15955
I have the following type definition:
data NumList n = NumList [Rational]
Then in my code I define some NumLists like so,
n1 = NumList [1, 2, 3]
n2 = NumList [4, 5, 6]
What I would like to do is this:
n3 = n1 + n2 -- Should be [5, 7, 9]
I tried defining this as so:
toList :: NumList n -> [Rational]
toList (NumList n) = n
(+) :: NumList -> NumList -> NumList
(+) x y = if length x == length y
then
zipWith (+) toList x toList y -- This probably isn't right, but I'll debug this later
else
error "NumLists must be same length to add"
The error I get is:
Ambiguous occurrence `+'
It could refer to either `NumList.+',
defined at NumList.hs:7:5
or `Prelude.+'
I don't see how this is ambiguous since Prelude.+ applies to the Num
class and NumList.+ only applies to the NumList type. Any guidance on this? Also a little bonus question: Is there a way to use pattern matching to remove the if expression from the (+) function?
Upvotes: 0
Views: 116
Reputation: 53871
The error right now is that there are 2 types of (+)
s defined, one for Prelude and yours. You can fix this by making NumList
an instance of the Num
type.
instance Num NumList where
(+) nl1 nl2 = implementPlus
(*) nl1 nl2 = implementTimes
(-) nl1 nl2 = implementMinus
abs nl = NumList (map abs (toList nl))
signum nl = NumList (map signum (toList nl))
fromInteger i = NumList [fromInteger i]
Now addition will call implemenPlus
and everything will be wonderful. As an added bonus, you can even write numeric literals, haskell will infer that they're a NumList
and turn them into a list of one element, quite nice for writing lots of them.
Also, for your bonus question, I'd just write it like this
(NumList n1) + (NumList n2) = NumList $ zipWith (+) n1 n2
This is what I'd expect using it, that the result is the length of the shortest list. If you really want it to blow up,
(NumList n1) + (NumList n2) |length n1 == length n2 =
NumList $ zipWith (+) n1 n2
| otherwise =
error "You done goofed"
This just uses guards, think of them as souped up if
s. And otherwise
is simply defined as
otherwise = True
in prelude.
Upvotes: 2