Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 正在获取类型参数的标识?_Haskell_Monoids - Fatal编程技术网

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)