Неоднозначное явление 'foldMap'

Я реализую Foldable для следующей структуры данных:

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.

Когда я реализую функцию, я получу ошибку, что она уже есть, но когда я не реализую функцию, я получу предупреждение, что функция отсутствует? Что я делаю неправильно?

1 ответ

Решение

Вам просто нужно сделать отступ fold а также foldMap декларации, так что они являются частью 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

Когда вы сделали их без отступа, машина увидела пустую instance объявление и две не связанные функции верхнего уровня под названием fold а также foldMap, Пустой экземпляр был источником ошибки "Нет явной реализации" (почему это предупреждение, а не ошибка, я не знаю). Ошибка "неоднозначного вхождения" была вызвана тем, что компилятор не мог определить, рекурсивны ли вызовы foldMap имели в виду неявно импортированные Prelude.foldMap или к Main.foldMap в вашем коде.

Другие вопросы по тегам