首页 文章

如何修复“无法演绎(Num(Sum a))因使用''”而引起的?

提问于
浏览
0

我从this lecture获取代码,但是我在下面的演示代码中遇到了错误:

newtype Sum a = Sum a
  deriving (Eq,Ord,Show)
getSum::Sum a -> a
getSum (Sum a) = a
instance Num a=>Monoid (Sum a)where
  mempty = Sum 0
  mappend = (+)
newtype  Product a = Product a
  deriving (Eq,Ord,Show)
getProduct ::Product a -> a
getProduct (Product a ) = a
instance Num a => Monoid (Product a ) where
  mempty = Product 1
  mappend = (*)

我收到以下错误消息(使用GHC 8.2.2):

Test.hs:40:13: error:
       ? Could not deduce (Num (Sum a)) arising from a use of ‘+’
         from the context: Num a
           bound by the instance declaration at Test.hs:38:10-30
       ? In the expression: (+)
         In an equation for ‘mappend’: mappend = (+)
         In the instance declaration for ‘Monoid (Sum a)’   
 | 40 |   mappend = (+)  

Test.hs:50:13: error:
    ? Could not deduce (Num (Product a)) arising from a use of ‘*’
      from the context: Num a
        bound by the instance declaration at Test.hs:48:10-37
    ? In the expression: (*)
      In an equation for ‘mappend’: mappend = (*)
      In the instance declaration for ‘Monoid (Product a)’
50 |   mappend = (*)

1 回答

  • 3

    通过将 mappend 定义为 (+) ,您说 Sum a 本身是 Num 的成员 . 相反,它只包含那些成员,所以 (+) 应该对这些成员进行操作 .

    instance Num a => Monoid (Sum a) where
        mempty                  = Sum 0
        mappend (Sum x) (Sum y) = Sum $ x + y
    

    同样适用于 Product

    instance Num a => Monoid (Product a) where
        mempty                          = Product 1
        mappend (Product x) (Product y) = Product $ x * y
    

    然后你的monoid实例按预期工作 .

    xs = map Sum [1..5]
    ys = map Product [1..5]
    mconcat xs  -- 15
    mconcat ys  -- 120
    

    或者,您可以按照讲座的代码并在您的新类型中派生 Num .

    -- from the linked lecture
    newtype Sum a = Sum a
      deriving (Eq, Ord, Num, Show)
    newtype Product a = Product a
      deriving (Eq, Ord, Num, Show)
    

相关问题