モナドのプログラミングにおいて、>>= 演算子の左右の項には厳しい制限がある。つまり >>= の左項は M a 型のモナド値であり、>>= の右項は a -> M a 型の関数でなくてはならない。このあたりの説明をスタックの pop 関数と push 関数を例にとってやってみる。 Prelude> import Control.Monad.State Prelude Control.Monad.State> :{ Prelude Control.Monad.State| pop :: State [a] a Prelude Control.Monad.State| pop = state (\s -> (head s, tail s)) Prelude Control.Monad.State| :} Prelude Control.Monad.State> runState pop [1,2,3] (1,[2,3]) つぎに、push 関数だが、これはスタックに積む値を引数に取るので型は push :: a -> State [a] a だ。 Prelude Control.Monad.State> :{ Prelude Control.Monad.State| push :: a -> State [a] a Prelude Control.Monad.State| push x = state (\s -> (x, (x:s))) Prelude Control.Monad.State| :} Prelude Control.Monad.State> runState (push 5) [1,2,3] (5,[5,1,2,3]) この push と pop を使ってスタックの先頭の要素を 10 倍にしてみる Prelude Control.Monad.State> runState (pop >>= \x -> return (10*x) >>= push) [1,2,3] (10,[10,2,3]) これは do 記法で記述したほうがわかりやすい。 Prelude Control.Monad.State> runState (do x <- pop; push (x * 10)) [1,2,3] (10,[10,2,3]) >>= 演算子の右項に置くべき a -> State s a 型の関数の作り方をやってみた。やや技巧的だが、これがわかれば、State モナドを自由に操ることができるようになる。 State モナドのプログラミングでは上に述べた state 関数で関数をラッピングする方法より、return, get, put, modify 関数などを使って do 記法でプログラムする方法もある。むしろ、こちらのほうがわかりやすいかもしれない。 Prelude Control.Monad.State> :{ Prelude Control.Monad.State| pop :: State [a] a Prelude Control.Monad.State| pop = do xs <- get; put (tail xs); return (head xs) Prelude Control.Monad.State| :} Prelude Control.Monad.State> runState pop [1,2,3] (1,[2,3]) Prelude Control.Monad.State> :{ Prelude Control.Monad.State| push :: a -> State [a] a Prelude Control.Monad.State| push x = do xs <- get; put (x:xs); return x Prelude Control.Monad.State| :} Prelude Control.Monad.State> runState (push 5) [1,2,3] (5,[5,1,2,3]) Prelude Control.Monad.State> runState (do x <- pop; push (x*10)) [1,2,3] (10,[10,2,3]) get, put 関数の動作は汎用的なので、State モナドのプログラミングはこちらを使うほうが王道だろう。
by tnomura9
| 2018-11-11 20:50
| Haskell
|
Comments(0)
|
カテゴリ
新型コロナウイルス 主インデックス Haskell 記事リスト 圏論記事リスト 考えるということのリスト 考えるということ ラッセルのパラドックス Haskell Prelude Ocaml ボーカロイド 圏論 jQuery デモ HTML Python ツールボックス XAMPP Ruby ubuntu WordPress 脳の話 話のネタ リンク 幸福論 キリスト教 心の話 メモ 電子カルテ Dojo JavaScript C# NetWalker ed と sed HTML Raspberry Pi C 言語 命題論理 以前の記事
最新のトラックバック
最新のコメント
ファン
記事ランキング
ブログジャンル
画像一覧
|
ファン申請 |
||