Class Haskell幺半群折叠式玫瑰树

Class Haskell幺半群折叠式玫瑰树,class,haskell,monoids,Class,Haskell,Monoids,我需要为Rose tree数据结构创建一个可折叠的实例: data Rose a = a :> [Rose a] deriving (Eq, Show) 具有以下与monoid和rose相关的类/实例: instance Functor Rose where fmap f (a :> bs) = (f a) :> (map (fmap f) bs) class Monoid a where mempty :: a (<

我需要为Rose tree数据结构创建一个可折叠的实例:

data Rose a = a :> [Rose a]
    deriving (Eq, Show)
具有以下与monoid和rose相关的类/实例:

instance Functor Rose where
    fmap f (a :> bs) = (f a) :> (map (fmap f) bs)

class Monoid a where
    mempty ::           a
    (<>)   :: a -> a -> a

instance Monoid [a] where
    mempty = []
    (<>)   = (++)
但我不知道为什么不行,有人能帮我吗

提前谢谢

致以最良好的祝愿,
Skyfe.

看来我找到了自己问题的答案

解决方案:

instance Foldable Rose where
    fold (a:>b) =  a <> (foldr (<>) mempty (map fold b))
实例可折叠Rose在哪里
折叠(a:>b)=a(折叠()记忆(地图折叠b))

必须首先将列表中的每个元素附加到head元素(并对绑定到这些玫瑰树的每个元素执行相同操作),然后将列表与非调整元素mempty一起折叠。

您的
折叠实现是正确的,没有理由更改它

问题是,
fold
不足以定义
Foldable
。发件人:

可折叠t类,其中源代码

可以折叠的数据结构

最小完整定义:
foldMap
foldr

因此必须定义
foldMap
foldr
(或两者都定义)。定义
foldMap
更简单、更自然(在许多情况下也更有效)。所以你应该写一些类似的东西:

import Data.Foldable
import Data.Monoid

data Rose a = a :> [Rose a]
    deriving (Eq, Show)

instance Foldable Rose where
    foldMap f (x :> xs) = f x <> foldMap (foldMap f) xs
导入数据。可折叠
导入数据.幺半群
数据玫瑰a=a:>[玫瑰a]
推导(等式,显示)
实例折叠式玫瑰在哪里
foldMap f(x:>xs)=f x foldMap(foldMap f)xs

这只是切点相关,但是如果您意识到玫瑰树与中的
Cofree[]
相同,那么您可以从中免费获得一个可折叠的
实例,如下所示:

import Control.Comonad.Cofree
import Data.Foldable as F

type RoseTree = Cofree []
将其加载到GHCi中:

λ> let tree = 1 :< [1 :< [], 2 :< [], 3 :< []] :: RoseTree Int
λ> :t F.foldr (+) 0 tree
F.foldr (+) 0 tree :: Int
λ> F.foldr (+) 0 tree
7
λ>let tree=1:<[1:<[],2:<[],3:<[]]::RoseTree Int
λ> :t F.foldr(+)0树
F.foldr(+)0树::Int
λ> F.foldr(+)0树
7.

您也可以派生可折叠的,或者编写自己的实现(就像您所做的那样)。

尽管OP说他/她已经找到了答案,但解决方案缺少基本情况:

instance Foldable Rose where
    fold (a:>[]) = a <> mempty
    fold (a:>b) =  a <> (foldr (<>) mempty (map fold b))
实例可折叠Rose在哪里
折叠(a:>[])=记忆
折叠(a:>b)=a(折叠()记忆(地图折叠b))

否则,函数折叠中的非穷举模式将被抛出。

与其更新问题中的解决方案,不如将其写在这里作为答案?很好,没有想到这种可能性!使用
{-LANGUAGE-DeriveFoldable-}
进行
派生(可折叠)
如何?您可能希望签出
容器
包中的
数据树
,它是Haskell平台的一部分,也随GHC一起提供。
λ> let tree = 1 :< [1 :< [], 2 :< [], 3 :< []] :: RoseTree Int
λ> :t F.foldr (+) 0 tree
F.foldr (+) 0 tree :: Int
λ> F.foldr (+) 0 tree
7
instance Foldable Rose where
    fold (a:>[]) = a <> mempty
    fold (a:>b) =  a <> (foldr (<>) mempty (map fold b))