モナドの入り口に立つ
Haskellを本格的に勉強しはじめて20日と少し経ち、関数型言語のイメージのようなものは大体つかめて来たと思うので、Haskellerの間で「難関」と言われている「モナド」に挑戦します。
IOや、List、Maybeがモナドだ、というのはいやというほど聞かされていたのですが、仕組みの分らないものを使うのは気が引ける性格なので、思い切って実際にモナドのインスタンスを作って動かしてみる事にしました。
module Signal where data Sig = Red | Yerrow | Blue instance Show Sig where show Red = "Red" show Yerrow = "Yerrow" show Blue = "Blue" data Signal a = Signal a instance Monad Signal where (>>=) (Signal a) f = f a return a = Signal a takeSignal :: Signal Sig -> Sig takeSignal (Signal a) = a nextSignal :: Sig -> Signal Sig nextSignal Blue = Signal Yerrow nextSignal Yerrow = Signal Red nextSignal Red = Signal Blue
普段対話モードでごにょごにょやる事が多いのでスクリプトの書き方がよく解らなくて七転八倒してしまいました・・・
稚拙なコードではありますが、一応ちゃんと動作します。
*Signal> takeSignal $ return Blue Blue *Signal> takeSignal $ return Blue >>= nextSignal Yerrow *Signal> takeSignal $ return Blue >>= nextSignal >>= nextSignal Red *Signal> takeSignal $ return Blue >>= nextSignal >>= nextSignal >>= nextSignal Blue
色々とツッコミ所はあると思いますが、ざっくりとしたモナドの「動き」を理解するには、これでOK・・・ですよね?
do記法については、関数型言語を勉強してる時に見た目が手続き指向すぎて敬遠していたのですが、これを足がかりにちゃんと勉強してみようと思います。
これまた車輪の再発明になってしまうのですが、Stateモナドというのを使うと、一時的な副作用を再現できるようですが、実際に活用する前に簡単な副作用を再現してみるのも面白そうです。