モナドについていろいろ抽象的に考えてもプログラムは書けないので、モナドのデータ型の中で一番わかりやすそうな Maybe モナドを使ったプログラムをつくってみた。
ます、Maybe モナドがどんなものかを知るために、Maybe モナドを戻り値に戻す lookup 関数の動作を見てみる。lookup 関数は、第1引数の値が、第2引数のタプルのリストの中のタプルの第1要素と一致すれば、そのタプルの第2要素を Just x の形で返し、一致が見られなかった場合は、Nothing をかえす。文章で表すより使ってみた方が早いので、以下に示す。 Hugs> lookup 1 [(1,2),(3,4)] Just 2 Hugs> lookup 0 [(1,2),(3,4)] Nothing そこで、このような Maybe モナドがどのように定義されているのか見てみる。 Hugs のコマンドプロンプトで次のように入力すると、 Hugs> :find Maybe エディターに、Prelude の内容が表示されるはずだ。そこで、maybe を検索していくと次のような記述を見つけることができる。 -- Maybe type --------------------------------------------------------------- data Maybe a = Nothing | Just a deriving (Eq, Ord, Read, Show) maybe :: b -> (a -> b) -> Maybe a -> b maybe n f Nothing = n maybe n f (Just x) = f x instance Functor Maybe where fmap f Nothing = Nothing fmap f (Just x) = Just (f x) instance Monad Maybe where Just x >>= k = k x Nothing >>= k = Nothing return = Just fail s = Nothing 第1段落を見ると、Maybe のデータ型が、Nothing と Just x であることが分かる。第4段落には bind 演算子 >>= の定義がある。これを見ると、Just x が >>= をはさんで 関数 k に渡されたときは、k x が実行され、Nothing が k に渡されると、Nothing が返されることがわかる。Nothing が渡されると k がどんな関数でも Nothing が返えるので、実質的には Just x が関数 k に渡されたときだけを考えてプログラムすればよい。 そこで、lookup の戻り値である Maybe モナドを受け取って、Maybe モナドがたのデータを返す testmaybe 関数をプログラムしてみる。testmaybe 関数が Maybe モナドを受け取ると言っても、>>= の定義を見ると関数 k には Just のデータ部分の x が渡っているので、testmaybe の型は、Int -> Maybe Int の形にすることになる。Just x から x を受け取った testmaybe が x を2倍して Just n の形で返すようにするには、次のようにプログラムする。 Hugs> :e testmaybe.hs (testmaybe.hs の内容) testmaybe :: Int -> Maybe Int testmaybe x = return (x * 2) それでは、こうして作った Maybe モナドの世界の新しい住人 testmaybe を動かしてみよう。 Hugs> :l testmaybe.hs まず、単純に Just 1 という Maybe モナドのデータを testmaybe に渡してみる。 Main> Just 1 >>= testmaybe Just 2 Just 1 のデータが Just 2 になって帰ってきているのでうまくいったようだ。それでは Nothing ではどうだろう。 Main> Nothing >>= testmaybe Nothing ちゃんと Nothing が返ってくる。それでは、lookup の戻り値を受けて見よう。 Main> lookup 1 [(1,2)] >>= testmaybe Just 4 また、testmaybe の戻り値を次々に testmaybe につなげていくこともできる。 Main> testmaybe 1 >>= testmaybe Just 4 Main> testmaybe 1 >>= testmaybe >>= testmaybe Just 8 このように、モナドの理論は難しいが、モナドの世界の住人を増やすのは意外に簡単だった。 モナドの世界でプログラミングをする限りは、関数がモナドの外の世界に影響することはないのでモジュール化されたプログラムを気楽に作ることができる。また、関数と関数を結び付ける bind 演算子 (>>=) のおかげで、要素的な働きをする関数を定義しておくと、複雑な処理も関数の結合だけで実現できてしまう。たとえば Maybe モナドの場合、データの取得が失敗した場合の if then else 制御文による記述を個々のプログラムで行う必要がなくなるのですっきりした処理の記述になる。 IO処理のために仕方なくモナドの世界のプログラムをするのではなく、積極的にモナドのプログラムを活用すると便利なのかもしれない。もちろん、もう少し Haskell が分かってからの将来の話になるが。
by tnomura9
| 2009-08-29 07:56
| Haskell
|
Comments(0)
|
カテゴリ
新型コロナウイルス 主インデックス Haskell 記事リスト 圏論記事リスト 考えるということのリスト 考えるということ ラッセルのパラドックス Haskell Prelude Ocaml ボーカロイド 圏論 jQuery デモ HTML Python ツールボックス XAMPP Ruby ubuntu WordPress 脳の話 話のネタ リンク 幸福論 キリスト教 心の話 メモ 電子カルテ Dojo JavaScript C# NetWalker ed と sed HTML Raspberry Pi C 言語 命題論理 以前の記事
最新のトラックバック
最新のコメント
ファン
記事ランキング
ブログジャンル
画像一覧
|
ファン申請 |
||