我有以下类型要成为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)
仅当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 bRun 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不同的方式实现自己,或者应该尝试为自己的半身像提出另一种结构。