Как Foldable знает реализацию mappend

Я изучаю Haskell с помощью " http://learnyouahaskell.com/ ". Я следую примеру BST (Binary Search Tree), который является экземпляром Foldable:

data Tree a = Nil | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)

instance F.Foldable Tree where
    foldMap f Nil = mempty
    foldMap f (Node x l r) = (F.foldMap f l) `mappend` (f x) `mappend` (F.foldMap f r)

Когда я бегу F.foldMap (\x -> [x]) testTree Я получаю список, который представляет сложенное дерево. Я реализовал свой собственный тип данных:

newtype OnlySum a = OnlySum {value :: a} deriving (Eq, Ord, Read, Show, Bounded)
instance Num a => Monoid (OnlySum a) where
    mempty = OnlySum 0
    OnlySum x `mappend` OnlySum y = OnlySum (x + y)

И запустил эту команду: F.foldMap (\x -> OnlySum x) testTree чтобы получить дерево, сложенное так OnlySum {value = 34},

Вопрос в том, как Foldable узнает определение mempty а также mappend в зависимости от типа возвращаемого значения функции f перешел к foldMap ? Выводит ли это это или есть способ для Haskell автоматически узнать, какое определение?

1 ответ

Решение

В определении foldMap мы видим, что для этого требуется экземпляр класса типов Monoid m, Так что Хаскелл знает, что mappend исходит от Monoid, Конкретный тип будет выведен, а затем Monoid Экземпляр класса типов разрешается на основе этого типа, и именно этот класс типов будет использоваться.

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