1

我正在为以下数据结构实现可折叠:

data Tree a = Leaf a | Node (Tree a) (Tree a) deriving Show

当我实现 fold 和 foldMap 时:

instance Foldable Tree where 

--fold :: Monoid a => Tree a -> a
fold (Leaf x) = x
fold (Node l r) = fold l `mappend` fold r

--foldMap :: Monoid b => (a -> b) -> Tree a -> b 
foldMap f (Leaf x) = f x
foldMap f (Node l r) = foldMap f l `mappend` foldMap f r

我会收到以下错误:

    Ambiguous occurrence ‘foldMap’
    It could refer to either ‘Main.foldMap’,
                             defined at Chapterh14.hs:57:1
                          or ‘Prelude.foldMap’,
                             imported from ‘Prelude’ at Chapterh14.hs:1:1
                             (and originally defined in ‘Data.Foldable’)

Chapterh14.hs:58:46:
    Ambiguous occurrence ‘foldMap’
    It could refer to either ‘Main.foldMap’,
                             defined at Chapterh14.hs:57:1
                          or ‘Prelude.foldMap’,
                             imported from ‘Prelude’ at Chapterh14.hs:1:1
                             (and originally defined in ‘Data.Foldable’)

Chapterh14.hs:71:13:
    Ambiguous occurrence ‘foldMap’
    It could refer to either ‘Main.foldMap’,
                             defined at Chapterh14.hs:57:1
                          or ‘Prelude.foldMap’,
                             imported from ‘Prelude’ at Chapterh14.hs:1:1
                             (and originally defined in ‘Data.Foldable’)

当我删除 foldMap 的定义时,我会收到以下警告:

    No explicit implementation for
      either ‘foldMap’ or ‘foldr’
    In the instance declaration for ‘Foldable Tree’
Ok, modules loaded: Main.

当我实现该功能时,我会得到它已经存在的错误,但是当我不实现该功能时,我会收到该功能丢失的警告?我究竟做错了什么?

4

1 回答 1

4

您只需要缩进您的foldfoldMap声明,以便它们成为instance.

instance Foldable Tree where
    --fold :: Monoid a => Tree a -> a
    fold (Leaf x) = x
    fold (Node l r) = fold l `mappend` fold r

    --foldMap :: Monoid b => (a -> b) -> Tree a -> b
    foldMap f (Leaf x) = f x
    foldMap f (Node l r) = foldMap f l `mappend` foldMap f r

当您将它们取消缩进时,机器会看到一个空声明和两个称为andinstance的不相关的顶级函数。空实例是“无显式实现”错误的来源(为什么这是一个警告而不是我不知道的错误)。“模棱两可的发生”错误是因为编译器无法判断递归调用是引用隐式导入的还是引用代码中的。foldfoldMapfoldMapPrelude.foldMapMain.foldMap

于 2017-05-05T11:36:56.950 回答