liftM はモナドの関数、lift はモナド変換子の関数だ。何かを持ち上げるという意味なのだろうが使い方がさっぱりわからない。こんなときは、単純な使い方を試してみるに限る。liftM と lift を試して見るためには、Control.Monad.State モジュールをインポートすると両方使える。 Prelude> import Control.Monad.State まず liftM からだ。最初は関数の型を見てみる。 Prelude Control.Monad.State> :t liftM liftM :: Monad m => (a1 -> r) -> m a1 -> m r m はモナドを表すので、これは a1 -> r 型の関数から m a1 -> m r 型の関数に変換されることがわかる。そこで、次のように foo という関数を作って試してみた。 Prelude Control.Monad.State> foo = liftM (*2) Prelude Control.Monad.State> :t foo foo :: (Monad m, Num r) => m r -> m r (*2) は数を2倍にする関数だから foo = liftM (*2) は m x の x の値を2倍にして m 2x を返す関数になる。 Prelude Control.Monad.State> foo (Just 2) Just 4 liftM の動作は意外と単純だった。こんどは lift に挑戦してみる。lift の説明はいろいろ読んでもよくわからなかったので、最も単純な例を試してみた。runStateT の引数に普通にモナドプログラムを渡すと、単に State モナドとして働く。 Prelude Control.Monad.State> runStateT (return 2) () (2,()) ところが、lift に Just 2 というMaybe モナドを渡すと、(2,()) というrunState のペアが Just にラッピングされて返されてくる。 Prelude Control.Monad.State> runStateT (lift (Just 2)) () Just (2,()) State モナドの中に Maybe モナドの値を放り込んだら、裏表が逆になって Just にラッピングされて戻されてきた。なんだかよくわからないが、ともかくState モナドのプログラムの中で Maybe モナドが使えることがわかる。そこで、もう少し State モナドらしいことをさせてみよう。 Prelude Control.Monad.State> runStateT (do x <- get; y <- lift (Just 3); return (x+y)) 7 Just (10,7) 状態の 7 と Just 3 の 3 が足し算されて値として戻されているが、そのペア (10, 7) は Just にラッピングされて戻ってくる。State モナドのプログラミングのなかで Maybe モナドの Just 3 の 3 を利用することができるが、その場合出力が Just (10,7) のように Maybe モナドになってしまっている。 しかし、lift の引数が IO モナドだとそのありがたみがもっとわかる。 Prelude Control.Monad.State> runStateT (do x <- get; y <- lift(getLine); return (x ++ y)) "hello, " world ("hello, world","hello, ") 出力にモナドのデータコンストラクタが表示されていないがこれは出力が IO モナドだからだ。 Prelude Control.Monad.State> :t runStateT (do x <- get; y <- lift(getLine); return (x ++ y)) "hello, " runStateT (do x <- get; y <- lift(getLine); return (x ++ y)) "hello, " :: IO ([Char], [Char]) このことは、StateTモナド変換子を使うことで、IOモナドのプログラムに状態を導入することができることを示している。つまり、2つのモナドを一緒に使うことができるのだ。これで StateT モナドの使い方がわかったわけではないが、少なくとも IO モナドのプログラムの中に State モナドによる状態を導入できることがわかったので、StateT モナド変換子をいろいろ試してみることができる気がしてきた。
by tnomura9
| 2018-11-20 00:03
| Haskell
|
Comments(0)
|
カテゴリ
新型コロナウイルス 主インデックス Haskell 記事リスト 圏論記事リスト 考えるということのリスト 考えるということ ラッセルのパラドックス Haskell Prelude Ocaml ボーカロイド 圏論 jQuery デモ HTML Python ツールボックス XAMPP Ruby ubuntu WordPress 脳の話 話のネタ リンク 幸福論 キリスト教 心の話 メモ 電子カルテ Dojo JavaScript C# NetWalker ed と sed HTML Raspberry Pi C 言語 命題論理 以前の記事
最新のトラックバック
最新のコメント
ファン
記事ランキング
ブログジャンル
画像一覧
|
ファン申請 |
||