trifecta の実験として、次の単純な関数を作成しました。
filterParser :: (a -> Bool) -> Parser a -> Parser a
filterParser cond p = do
a <- p
if cond a
then return a
else unexpected "condition failed!"
アイデアは、パーサーに条件を追加できるようにすることでした。たとえば (述語prime
が既に存在すると仮定して)、次のように記述
filterParser prime integer
します。素数のみを受け入れるパーサーを作成します。
単一の解析では問題ないようです:
> parseString (filterParser (> 'm') letter) mempty "z"
> Success 'z
> parseString (filterParser (> 'm') letter) mempty "a"
> Failure (interactive):1:2: error: unexpected
> condition failed!
しかし、「多数」では機能しません-比較してください:
> parseString (many $ filterParser (> 'm') letter) mempty "zzz2"
> Success "zzz"
> parseString (many $ filterParser (> 'm') letter) mempty "zzza"
> Failure (interactive):1:5: error: unexpected
> condition failed!
最後の例も返されることを望んでいましたSuccess "zzz"
。への呼び出しunexpected
は、解析全体を脱線させるように見えますが、これは私が望んでいたものではありません。