はじめに
Monad の(数学的な)理解とHaskell のMonad インスタンスがわかっているかどうかは全く違って、私は現在後者でつまずいています。
State Monadの勉強をStateモナドで遊んでみようでさせてもらいながら、こっちを読んでいます、そこで出会った不思議な警告文の紹介です。
State Monad を勉強中に出くわした不思議な現象。
ここで扱っているのは
[(a,Rational)]
なる型で与えられる、何か値(a)とそれにくっついている確率(Rational)のリストを素朴にラップしてタプルのひとつ目の要素(と確率が確率でいられるようにキチンと処置を施したもの)を目標にMonadにしましょうということです。
まずはFunctor のインスタンスにしなくてはいけませんが、これは簡単で確率(タプルの二個目)には触らずタプルの一個目だけに作用させるという方針で実装します。
そのあとreturn とbind(>>=) を定義するわけですが、定義しただけだと次のように怒られました。
[2 of 2] Compiling FAFMM_14 ( FAFMM_14.lhs, interpreted )
FAFMM_14.lhs:1183:12:
No instance for (Applicative Prob)
arising from the superclasses of an instance declaration
In the instance declaration for ‘Monad Prob’
Failed, modules loaded: AFOM_13.
該当する箇所はここ。
1183 > instance Monad Prob where
1184 > return x = Prob [(x,1%1)]
1185 > m >>= f = flatten (fmap f m)
1186 > fail _ = Prob []
1190 > -- instance Applicative Prob where
1191 > -- pure x = Prob [(x,1%1)]
1192 > -- (<*>) :: Applicative f => f (a -> b) -> f a -> f b
1193 > -- (Prob f) <*> (Prob xs) =
仕方ないのでApplicative のインスタンスを定義しようと考えてる途中で手癖でファイルを閉じた時に発見しました。
すなわち1190行のインスタンスとしての宣言だけコメントアウトをほどくと
FAFMM_14.lhs:1190:12: Warning:
No explicit implementation for
‘pure’ and ‘<*>’
In the instance declaration for ‘Applicative Prob’
Ok, modules loaded: FAFMM_14, AFOM_13.
となり、定義は空だけど通るという謎現象。
確かヒエラルキー的には
Monad \subset Applicative \subset Functor
なのだが、Haskell にはApplicative があとから導入された経緯があって、Monad のインスタンスが必ずしもApplicative のインスタンスじゃなくても良かったということだというのがここの部分の念頭にあるのだと理解しているのだが、いつの間にかちゃんとこのヒエラルキーを踏襲しましょうとなったのだろうか?
疑問点
今のところApplicative のインスタンスの定義が書けなくてどうしようか考えているところです。
どなたかいい案があれば教えていただけませんか?
(Monad インスタンスから決まりそうな気がするのですがこんがらがっていて、、、もう少し考えてみます)
また設計段階でMonad しか使わん、Applicative としては使わないとわかっている場合この警告を消せる”良い”宣言方法、どなたがご存知ありませんか?
今のところインスタンスが空なApplicative の宣言だけが放置されているので大変気持が悪くって困っています。