私はHaskell モノイドとその使用法を調べてきました。これにより、モノイドの基本についてかなりよく理解できました。ブログ投稿で紹介されているものの 1 つは 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
m@(Maximum (Just x)) `mappend` Maximum Nothing = m
Maximum Nothing `mappend` y = y
m@(Maximum (Just x)) `mappend` n@(Maximum (Just y))
| x > y = m
| otherwise = n
特定の型の Maximum モノイドを構築することは非常に簡単です。たとえば、Num などは非常に簡単ですが、何にでも役立つようにしたいと考えています (その Any が 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の使用の両方に関して)。
- 編集 -
ポール・ジョンソンは、以下のコメントで、メイビーを除外することを提案しました。私の最初の試みは次のようになります。
newtype Minimum a = Minimum { getMinimum :: a }
deriving (Eq, Ord, Read, Show)
instance Ord a => Monoid (Minimum a) where
mempty = ??
m@(Minimum x) `mappend` n@(Minimum y)
| x < y = m
| otherwise = n
しかし、 a の mempty 値がどうあるべきかを知らずに mempty を表現する方法がわかりません。これをどのように一般化できますか?