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"関数に戻ります。