微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将 Pair 定义为 Monoid?

如何解决如何将 Pair 定义为 Monoid?

我的数据类型 Pair 定义为

data Pair a b = Pair a b

我想让它成为幺半群。这是我的定义。

instance (Monoid a,Monoid b) => Monoid (Pair a b) where
    mempty = Pair mempty mempty
    mappend (Pair x1 y1) (Pair x2 y2) = Pair (mappend x1 x2) (mappend y1 y2)

但是,我收到了以下错误

foldable.hs:3:10: error:
    • Could not deduce (Semigroup (Pair a b))
        arising from the superclasses of an instance declaration
      from the context: (Monoid a,Monoid b)
        bound by the instance declaration at foldable.hs:3:10-49
    • In the instance declaration for ‘Monoid (Pair a b)’
  |
3 | instance (Monoid a,Monoid b) => Monoid (Pair a b) where
  |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

出了什么问题?

解决方法

mappend 不再是真正的 Monoid 方法。你可以实现它,但它应该只是 (<>) 的同义词,它属于 Monoid 的超类 Semigroup。要实现 Monoid,您还必须实现 Semigroup,并将 mappend 的定义放在那里,命名为 (<>)

,

将来 GHC.Generics 将具有 Generically wrapper,允许派生两个实例 via Generically (Pair a b)

{-# Language DeriveGeneric #-}
{-# Language DerivingStrategies #-}
{-# Language DerivingVia #-}

import GHC.Generics

-- >> mempty @(Pair String ())
-- Pair "" ()
--
-- >> Pair "hello" () <> Pair " " undefined <> Pair "world" ()
-- Pair "hello world" ()
data Pair a b
  deriving
  stock Generic

  deriving (Semigroup,Monoid)
  via Generically (Pair a b)

这已经可以通过 generic-data 实现。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。