Откуда Foldable знает реализацию mappend

Я изучаю Haskell с помощью "http://learnyouahaskell.com". Я следую примеру BST (Двоичное дерево поиска), которое является экземпляром 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 автоматически узнать, какой Определение?


person OneEyeQuestion    schedule 14.10.2014    source источник


Ответы (1)


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

person lmm    schedule 14.10.2014
comment
Так что это в основном полиморфизм, не так ли? - person OneEyeQuestion; 15.10.2014
comment
@OneEyeQuestion Да, это просто полиморфизм возвращаемого типа. - person bheklilr; 15.10.2014
comment
Да, поэтому типы делают больше, чем создают вам проблемы. Типы заставляют вас выполнять скучный код времени выполнения. Когда написание типов избавляет вас от написания кода, возможно, с ними даже стоит смириться. - person pigworker; 15.10.2014