我有以下类型定义:
data NumList n = NumList [Rational]
然后在我的代码中我定义了一些像这样的NumLists,
n1 = NumList [1, 2, 3]
n2 = NumList [4, 5, 6]
我想做的是:
n3 = n1 + n2 -- Should be [5, 7, 9]
我尝试将其定义为:
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"
我得到的错误是:
Ambiguous occurrence `+'
It could refer to either `NumList.+',
defined at NumList.hs:7:5
or `Prelude.+'
我不知道这是多么模糊,因为Prelude。+适用于Num
类和NumList。+仅适用于NumList类型。对此有何指导?还有一个小问题:是否有办法使用模式匹配从(+)函数中删除if表达式?
答案 0 :(得分:2)
现在的错误是定义了(+)
的两种类型,一种用于Prelude和你的。{1}}。您可以通过NumList
Num
类型的实例来解决此问题。
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]
现在添加将调用implemenPlus
,一切都会很精彩。作为额外的奖励,您甚至可以编写数字文字,haskell会推断它们是NumList
并将它们转换为一个元素的列表,非常适合编写大量元素。
另外,对于你的奖金问题,我只是这样写的
(NumList n1) + (NumList n2) = NumList $ zipWith (+) n1 n2
这是我期望使用它,结果是最短列表的长度。如果你真的希望它爆炸,
(NumList n1) + (NumList n2) |length n1 == length n2 =
NumList $ zipWith (+) n1 n2
| otherwise =
error "You done goofed"
这只是使用警卫,将它们视为加强if
s。 otherwise
简单地定义为
otherwise = True
在前奏中。