>>> parse (many even') "numbers" [0,0,2,4,9999]
Right [0,0,2,4]

>>> parse (many (zero <|> odd') >> eof) "numbers" [0,1,1,3,5,8]
Left "numbers" (line 1, column 6):
unexpected 8
expecting zero, odd or end of input

[Int]だとおふざけだが、複雑な何かだと便利かもしれない1

Monad m => Stream [tok] m tokとあるので、listに包めば何でもparse可能に見える
しかしStream s m Char =>制約の代わりに(Stream s m tok, Eq tok) =>なものが見当たらない
標準のsatisfyさえ:: Stream s m Char => (Char -> Bool) -> ParsecT s u m Charと、Charしか受け入れてくれない2
仕方がないので仕方なくなかった(追記)satisfyを再定義する

updatePos :: SourcePos -> Column -> SourcePos
updatePos p n = setSourceColumn p (sourceColumn p + n)

satisfy' :: (Stream s m t, Show t) => (t -> Bool) -> ParsecT s u m t
satisfy' f = tokenPrim show
    (\ pos _ _ -> updatePos pos 1)
    (\ c -> if f c then Just c else Nothing)

Text.Parsec.Charのほぼ全ての関数3satisfy経由で定義されているので、
Text.Parsec.Intを作ることが可能になる

zero :: (Num a, Eq a, Stream s m a, Show a) => ParsecT s u m a
zero = satisfy' (== 0) <?> "zero"
even', odd' :: (Integral a, Stream s m a, Show a) => ParsecT s u m a
even' = satisfy' even <?> "even"
odd' = satisfy' odd <?> "odd"

参考

追記

定義されてた

Text.Parsec.Combinator.anyToken
anyToken :: (Stream s m t, Show t) => ParsecT s u m t

なので

satisfy' f = try $ lookAhead (anyToken >>= (\ x -> if f x then return x else unexpected $ show x))

としても良い


[Int]をparsecでパースする

  1. 便利でないかもしれない 

  2. parser-libraryなので当然 

  3. Text.Parsec.Char.string以外の全て