Text.Parsec.Char
satisfy 関数
基本的なパーサの作り方が分かったので、Text.Parsec.Char で定義されているたくさんのパーサの作り方をのぞいてみた。すると、驚いたことに大半が satisfy という関数を使ってパーサを作っていた。satisfy を使っているパーサの一覧を次に示す。oneOf cs = satisfy (\c -> elem c cs) noneOf cs = satisfy (\c -> not (elem c cs)) space = satisfy isSpace <?> "space" upper = satisfy isUpper <?> "uppercase letter" lower = satisfy isLower <?> "lowercase letter" alphaNum = satisfy isAlphaNum <?> "letter or digit" letter = satisfy isAlpha <?> "letter" digit = satisfy isDigit <?> "digit" hexDigit = satisfy isHexDigit <?> "hexadecimal digit" octDigit = satisfy isOctDigit <?> "octal digit" char c = satisfy (==c) <?> show [c] anyChar = satisfy (const True)
satisfy のコード
satisfy のコードは次のようになるが、tokenPrim を利用して定義されている。
satisfy f = tokenPrim (\c -> show [c]) (\pos c _cs -> updatePosChar pos c) (\c -> if f c then Just c else Nothing)
satisfy を使う
satisfy は一般のユーザも使用できるので、試してみた。
Prelude> :m Text.Parsec Prelude Text.Parsec> parseTest (satisfy (< 'd')) "abc" 'a'
letter や digit がブラックボックスでなくなったので、パーサモナドが活用しやすくなった気がしてきた。