我有以下类型要成为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
上面的内容不适用于
Int
,因为Int
不是Monoid
。有两个非常受欢迎的候选项(ℕ,+,0)和(ℕ,×,1)。但是,您可以使用 Sum
,它是前一个monoid的表示形式。因此,最后一行正文中的
mempty
不是我们正在定义的mempty
,而是mempty
类型的a
。话虽如此,如果您这样定义一个
Monoid Tree
,则意味着您考虑使用Node mempty (Node mempty a b) c == Node mempty a (Node mempty b c)
,因为这是类半身定律所必需的。因此,此处deriving Eq
与mappend
并不完全处于“和谐”状态。 mappend
运算符(在数学上通常表示为⊕)应满足条件∀a,b,c∈S:a⊕(b⊕c)=(a⊕b)⊕c。您或者应该以不同的方式实现
Eq
,或者应该尝试为monoid设计另一个结构。
关于haskell - 获取类型参数的标识?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56099868/