Как 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
Экземпляр класса типов разрешается на основе этого типа, и именно этот класс типов будет использоваться.