Haskell 正在获取类型参数的标识?
我有以下类型,我想成为Haskell 正在获取类型参数的标识?,haskell,monoids,Haskell,Monoids,我有以下类型,我想成为Monoidtypeclass的实例。我不知道如何将参数化字段设置为标识。使用参数化类型获取该类型的标识时,有什么方法吗 data Tree a=Leaf a | Node a (Tree a) (Tree a) |Empty deriving (Eq,Show) instance Monoid Tree where mempty=Empty mappend a Empty=a mappend a b=Node (identity) x y 如您
Monoid
typeclass的实例。我不知道如何将参数化字段设置为标识。使用参数化类型获取该类型的标识时,有什么方法吗
data Tree a=Leaf a | Node a (Tree a) (Tree a) |Empty deriving (Eq,Show)
instance Monoid Tree where
mempty=Empty
mappend a Empty=a
mappend a b=Node (identity) x y
如您所见,我需要将简单字段设置为参数类型的标识
范例
mappend::Tree Int
mappend (Leaf 1) (Leaf 2)=Node 0 (Leaf 1) (Leaf 2)
mappend::Tree []
mappend (Leaf [1,2])(Leaf [2,3])=Node [] (Leaf [1,2])(Leaf [2,3])
只有当
a
本身也是Monoid
类型时,才会发生这种情况,因此我们可以这样写:
instance Monoid a => Monoid (Tree a) where
mempty = Empty
mappend Empty a = a
mappend a Empty = a
mappend a b = Node mempty a b
实例幺半群a=>幺半群(树a)其中
mempty=空
mappend空a=a
mappend a空=a
mappend a b=节点成员a b
上述方法不适用于Int
,因为Int
不是Monoid
。有两位非常受欢迎的候选人(ℕ, +, 0)及(ℕ, ×, 1). 但是,您可以使用它来表示前一个幺半群
因此,最后一行正文中的mempty
不是我们定义的mempty
,而是a
类型的mempty
如所说,如果你定义了一个<代码>幺半群树< /代码>,那意味着你考虑一个<代码> Node mempty(节点MimpTyA B)C==节点MypTy A(节点MimpTy B C)< /代码>,因为这是幺半群法则所要求的。因此,
导出的Eq
在这里与mappend
不完全协调。mappend
运算符(在数学中通常表示为⊕), 应该满足条件∀ a、 b、c和S:a⊕(b)⊕c) =(a)⊕(b)⊕c
你或者应该以不同的方式实现
Eq
,或者你应该尝试为你的monoid提出另一种结构。这不是一个答案,但它太长了,无法发表评论。正如Willem Van Onsem所建议的,你的monoid
实例是不合法的。我怀疑你可能想要两件事中的一件:
游离岩浆
一种类型上的游离岩浆可以定义
data Magma a = Branch (Magma a) (Magma a) | Leaf a | Empty
deriving Show
这不是一个自然的幺半群,但有时假装它是一个是有用的:
instance Monoid (Magma a) where
mempty = Empty
mappend = Branch
-- For recent GHC, add this instance
instance Semigroup (Magma a) where
(<>) = Branch
(这原来是函子树a
上定义的自由单子
data TreeF a b = NodeF a b b
但我们并不需要深入了解这意味着什么。)
树a的monad操作是一种“嫁接”,树叶被树代替
instance Functor (Tree a) where
fmap f (Leaf b) = Leaf (f b)
fmap f (Node a l r) = Node a (fmap f l) (fmap f r)
instance Applicative (Tree a) where
pure = Leaf
(<*>) = ap
liftA2 = liftM2
instance Monad (Tree a) where
Leaf b >>= f = f b
Node a l r >>= f = Node a (l >>= f) (r >>= f)
实例函子(树a),其中
fmap f(叶b)=叶(叶b)
fmap f(节点a l r)=节点a(fmap f l)(fmap f r)
实例应用程序树(a),其中
纯=叶
()=ap
liftA2=liftM2
实例Monad(树a)其中
叶b>>=f=FB
节点a l r>>=f=节点a(l>>=f)(r>>=f)
您可以将>=
视为支持某种垂直附加,即树从叶子向下生长
instance Functor (Tree a) where
fmap f (Leaf b) = Leaf (f b)
fmap f (Node a l r) = Node a (fmap f l) (fmap f r)
instance Applicative (Tree a) where
pure = Leaf
(<*>) = ap
liftA2 = liftM2
instance Monad (Tree a) where
Leaf b >>= f = f b
Node a l r >>= f = Node a (l >>= f) (r >>= f)