覆盖某些类型的+运算符

时间:2013-10-19 02:41:43

标签: haskell

我有以下类型定义:

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表达式?

1 个答案:

答案 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

在前奏中。

相关问题