Wikiエンジンの開発
12.3 CGIの処理
loadContextの続き
まだまだ続きます、loadContext。
昨日は"dropComment"関数まで見ました。
今日は"parseLinePlain"関数です。
"parseLinePlain"関数の定義はこんな感じ。
parseLinePlain line | isBlank line = [] | otherwise = let (k, ('=':v)) = break (== '=') . strip $ line in [(strip k, strip v)]
引数"line"にはコメントを削除された(dropped)"./config"フイルの各行が入ってきます。
では中身を見ていきます。
二つの引数に関するガードで分岐されています。
一つ目が"line"に"isBlank"関数を適用してTrueを返すガード。
"isBlank"関数は以下の定義です。
- TextUtil.hs
isBlank :: String -> Bool isBlank = all isSpace
まぁ、おそらく指定された文字列がスペースで埋め尽くされてるかどうか判定しているのでしょう。
でもちょっと気になるので中身を見ていきます。
まず"all"って何?
これはPreludeモジュールで定義されています。
foldr :: (a -> b -> b) -> b -> [a] -> b foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) and, or :: [Bool] -> Bool and = foldr (&&) True all p = and . map p
う〜ん、深い!
引数のリストの全要素に対して、第一引数の関数を適用して
全ての結果がTrueの場合、Trueを返す…と思うのですが、
きちんと中を見ていきます。
これを馬鹿正直に展開(簡約?)してみると、
all isSpace -- and . map isSpace -- (foldr (&&) True) . map isSpace
ここまでは分かりました。
ここからがやっかいです。
関数合成の右辺は簡単です。
"isBlank"関数の第二引数のリストの全要素に対して"isSpace"関数を適用して、その結果をリストにします。
ちなみに"isSpace"関数はCharモジュールで定義されています。
isSpace c = c `elem` " \t\n\r\f\v\xA0" -- Only Latin-1 spaces recognized
スペース文字だけじゃなく、タブや改行もスペースとして扱ってるんですね。
ちなみに"elem"関数はPreludeモジュールで定義されています。
or = foldr (||) False any, all :: (a -> Bool) -> [a] -> Bool any p = or . map p elem, notElem :: (Eq a) => a -> [a] -> Bool elem x = any (== x)
あらら?また"foldr"関数が出てきた。
"isBlank"関数を読み解くには"foldr"関数の理解が必須なわけですね。
今日はここまで!