07

18

[Haskell] Stateモナドの定義のうち、バインド(>>=)の定義がわかりにくい

2013.07.18(23:37)

Stateモナドの定義のうち、バインド(>>=)の定義がわかりにくい

-- newtypeは既存の型を別の型にくるむもの。
-- State型の中にいれたものはs -> (a,s)型の関数。
-- その関数をStateモナドに適用して評価した値を求めるのがrunState。

newtype State s a = State { runState :: s -> (a, s) }

-- State s型をMonad型クラスのインスタンスにする。
instance Monad (State s) where

-- returnはState型の中に最低限の関数として ¥s -> (x, s) をいれたもの。
-- return :: a -> State s a
return x = State $ ¥s -> (x, s)

-- (>>=) :: State s a -> (a -> State s b) -> State s b
State h >>= f = State $ ¥s -> let (a, newState) = h s
                    State g = f a
                  in g newState ★

get :: State a a
get = State (¥s -> (s, s))
put :: a -> State a ()
put s = State (¥_ -> ((), s))

-- の★の部分が何をやっているのかよくわからない。ちょっと変形してみる。
-- State hの中に入っている関数hに今の状態sを適用するとは、
-- runState (State h) s していることと同じである。
-- runStateすると、(値,新しい状態) として、(a,s')が返ってくる。 
-- 2段階目、fは、(a -> State s b)型の関数なので
-- f aを求めるとState s b型になり、それに状態s'を適用するのは
-- やはりrunStateしていることと同じで、runState (f a) s'と書ける。
-- runStateすると、(値,新しい状態) として、(a',s'')が返ってくる。
 
-- (>>=) :: State s a -> (a -> State s b) -> State s b
State h >>= f = State $ ¥s -> let
                   (a,s') = runState (State h) s
                   (a',s'') = runState (f a) s'
                  in (a',s'')
ここでState hをmと書くと
m >>= f = State $ ¥s -> let (a,s') = runState m s
                (a',s'') = runState (f a) s'
              in (a',s'')

つまり
m >>= f = State $ ¥s -> let (a,s') = runState m s
              in runState (f a) s'

こう書くとわかりやすい。これはバインド(>>=)の定義。

プロフィール

島敏博

Shima Toshihiro 島敏博
信州アルプスハイランド在住。HaskellとElixirが好き。組み込みソフトウェアアーキテクト、C++プログラマ、山歩き、美術館巡り、和食食べ歩き、日本赤十字社救急法指導員、インデックス投資、クラシック音楽、SESSAME会員、状態マシン設計、モデル駆動開発、ソフトウェアプロダクトライン、Rubyist、実践ビジネス英語

■ ツイッター
http://twitter.com/saltheads
■ Facebook
http://www.facebook.com/saltheads
■ Qiita
http://qiita.com/saltheads

印刷する場合は、ブラウザの印刷メニューではなく、このページの上から3cmくらいの青いところにある、「印刷」を押してみてください。少しうまく印刷できます。まだ完全ではないのですが、これで勘弁してください。


カテゴリ
最新記事
月別アーカイブ
最新コメント
検索フォーム
リンク
sessame
RSSリンクの表示