Подтвердить что ты не робот

Напишите максимальный моноид, используя, возможно, в Haskell

Я пережил моноиды 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. Как я могу обобщить это?

4b9b3361

Ответ 1

Функция, переданная в foldMap, должна возвращать моноид, в данном случае типа Maximum a:

> foldMap (Maximum . Just) [1,2,3]
Maximum {getMaximum = Just 3}