Я пережил моноиды Haskell и их использование, что дало мне довольно хорошее представление об основах моноидов. Одна из вещей, введенных в сообщение в блоге, - это моноид Any, и его использование выглядит следующим образом:
foldMap (Any . (== 1)) tree
foldMap (All . (> 1)) [1,2,3]
В том же ключе я пытался создать моноидный максимум и придумал следующее:
newtype Maximum a = Maximum { getMaximum :: Maybe a }
deriving (Eq, Ord, Read, Show)
instance Ord a => Monoid (Maximum a) where
mempty = Maximum Nothing
[email protected](Maximum (Just x)) `mappend` Maximum Nothing = m
Maximum Nothing `mappend` y = y
[email protected](Maximum (Just x)) `mappend` [email protected](Maximum (Just y))
| x > y = m
| otherwise = n
Я мог бы построить моноид Maximum для определенного типа - например, Num, например, довольно легко, но хочу, чтобы он был полезен для чего-либо (с очевидным требованием, чтобы что-то было экземпляром Ord).
На данный момент мой код компилируется, но об этом. Если я попытаюсь запустить его, я получаю следующее:
> foldMap (Just) [1,2,3]
<interactive>:1:20:
Ambiguous type variable `a' in the constraints:
`Num a' arising from the literal `3' at <interactive>:1:20
`Monoid a' arising from a use of `foldMap' at <interactive>:1:0-21
Probable fix: add a type signature that fixes these type variable(s)
Я не уверен, что это потому, что я называю это неправильным, или потому, что мой моноид неверен, или и то, и другое. Я был бы признателен за любые рекомендации о том, где я ошибаюсь (как с точки зрения логических ошибок, так и без идиоматического использования Haskell, поскольку я очень новичок в языке).
- EDIT -
Пол Джонсон, в комментарии ниже, предложил оставить "Возможно". Моя первая попытка выглядит так:
newtype Minimum a = Minimum { getMinimum :: a }
deriving (Eq, Ord, Read, Show)
instance Ord a => Monoid (Minimum a) where
mempty = ??
[email protected](Minimum x) `mappend` [email protected](Minimum y)
| x < y = m
| otherwise = n
но я не понимаю, как выразить mempty, не зная, что должно быть значением mempty. Как я могу обобщить это?