Wikiエンジンの開発
13.3 CGIの処理
いろいろ混乱してきたので今日はひとまず"mcons"関数をしっかり理解しよう。
でも"mcons"関数だけを見て理解しようとしても難しいです。
そこで、"sequence"関数を簡単な引数に適用してみて感じを掴みとってみよう。
"sequence"関数に与える引数の型は
Monad => [m a]
なので、適当に
[Just 1, Just 2, Just 3]
としてみます。
では始めます。
sequence [Just 1, Just 2, Just 3] foldr mcons (return []) [Just 1, Just 2, Just 3] mcons (Just 1) (foldr mcons (return []) [Just 2, Just 3]) mcons (Just 1) (mcons (Just 2) (foldr mcons (return []) [Just 3])) mcons (Just 1) (mcons (Just 2) (mcons (Just 3) (foldr mcons (return []) []))) mcons (Just 1) (mcons (Just 2) (mcons (Just 3) (return [])))
これで後は"mcons"関数を展開するだけになりました。
"foldr"関数、なかなかイメージしにくい関数ですが、
こうやって形でみると分かりやすいですね。
つまり、こんな感じでリストを展開するわけですね。
foldr 関数 最終値 リスト (関数 リスト要素1 (関数 リスト要素2 (関数 リスト要素3 ・・・ (関数 リスト最終要素 最終値))・・・)
閑話休題。
"sequence"関数の続きです。
一つ一つ攻めていきます。
mcons (Just 3) (return []) (Just 3) >>= \x -> (return []) >>= \y - > return (x:y)
ここで"x","y"には何が入っているんだろう?
Prelude> Just 3 >>= \x -> (return []) >>= \y -> return (x:y) Just [3]
あぁ、">>="演算子でつないでいく中で非モナド化しているんですね。
つまり
Just 3 -- → 3 return [] -- → []
となっているわけです。
では"sequence"関数の続きを。
mcons (Just 2) (Just [3])) (Just 2) >>= \x -> (Just [3]) >>= \y -> return (x:y)
これはどうなるんだろう?
Prelude> (Just 2) >>= \x -> (Just [3]) >>= \y -> return (x:y) Just [2,3]
演算をつないでいく中で、Nothingが現れるのでそこで処理が終了となっています。
"sequence"関数を片付けましょう。
mcons (Just 1) Just [2,3] Just [1,2,3]
今日はここまで!
明日は"mapM"関数に戻ります。