Parsec コンビネータ count
count n p
count n p パーサコンビネータは第1引数に Int 値をとり、第2引数にパーサをとり、パターン p の n 回の繰り返しのパターンにマッチして、その値をリストにして返すパーサを返す。ちょっとややこしいが、実験してみる。Prelude Text.Parsec> foo = (count 2 (string "bar")) :: Parsec String () [String]Prelude Text.Parsec> parseTest foo "barbarbarbar" ["bar","bar"]
上の実験は、count コンビネータが戻り値としてパーサを返すことを強調したかったのだが、動作の理解のためには次の例のほうが分かりやすいだろう。
Prelude Text.Parsec> parseTest (count 2 (string "buz")) "buzbuzbuz" ["buz","buz"]
myCount
この count パーサも簡単な Haskell のプログラムで定義されている。次の myCount がそのプログラムだ。
Prelude Text.Parsec> myCount n p | n <= 0 = return [] | otherwise = sequence (replicate n p)
myCount は count と同じように使える。
Prelude Text.Parsec> parseTest (myCount 2 (string "buz")) "buzbuzbuz" ["buz","buz"]
sequence
上のプログラムで sequence はモナドのリストを引数にとり、順次実行する関数だ。
Prelude Text.Parsec> sequence [(putStrLn "foo"), (putStrLn "bar"), (putStrLn "buz")] foo bar buz [(),(),()]
replicate
また replicate n p は要素 p を n 個含むリストを作る。
Prelude Text.Parsec> replicate 3 "foo" ["foo","foo","foo"]
したがって sequence (replicate n p) はパーサ p を n 回マッチさせるという意味になる。
Parsec のコンビネータは実際は Haskell のスニペットなので Hackage でソースを見るとその意味が分かることが多い。