获取类型参数的标识?

Ber*_*ian 2 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
Run Code Online (Sandbox Code Playgroud)

如您所见,我需要将简单字段设置为参数类型的标识。

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])
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 9

仅当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
Run Code Online (Sandbox Code Playgroud)

上面的内容不适用于Int,因为Int不是Monoid。有两个非常受欢迎的候选项(ℕ,+,0)(ℕ,×,1)。但是,您可以利用Sum其中的一个代表前半身像。

mempty最后一行的身体因此没有mempty我们定义,但mempty类型a

话虽如此,如果您定义一个Monoid Treelike,则意味着您要考虑a Node mempty (Node mempty a b) c == Node mempty a (Node mempty b c),因为这是monoid法则所必需的。因此,此处与此处deriving Eq并不完全“ 和谐mappend。的mappend操作员(在数学通常表示为),应该满足条件∀A,B,c∈S:a⊕(b⊕c)=(a⊕b)⊕c

您或者应该以Eq不同的方式实现自己,或者应该尝试为自己的半身像提出另一种结构。