如何将 Pair 定义为 Monoid?
How can I define Pair as a 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 which allows deriving both instances 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)
已经可以做到这一点
我的数据类型 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 which allows deriving both instances 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)
已经可以做到这一点