3

76ページで、関数をパーサーとして定義します。itemこれは、を取り、String返す[(Char, String)][]、失敗した場合に返される関数です。

sat78ページで、述語を取り、pその周りにパーサー構造を「ラップ」する関数を定義します。

p :: (Char -> Bool) -> Parser Char
sat p = do x <- item
           if p x then return x else failure

私が理解していないのはの魔法<-ですか?の結果がitem空でない場合、この演算子はリストをアンラップし、タプルから最初の項目をフェッチする必要があります。そうでない場合は、述語を詰まらせないものを生成する必要があります。私は何が欠けていますか?

4

2 に答える 2

3
do x <- item
   if p x then return x else failure

これは糖衣構文です

item >>= (\x -> if p x then return x else failure)

>>=モナディックバインド演算子です。

あなたが見逃しているのは>>=Parserタイプの定義は何ですか?(本のどこに定義されたMonadインスタンスがありますか?それは始まります。)Parserinstance Monad Parser where

于 2012-09-29T13:23:11.877 に答える
1

do表記は、モナド演算子のアプリケーションに合わせて脱糖されます(>>=)。より正確には、の定義はsat次の定義に脱糖されます。

sat p :: (Char -> Bool) -> Parser Char
sat p =
  item >>= \x -> if p x then return x else failure

オペレーター(>>=)は最初にitemパーサーを入力に適用します。正しく観察したように、このパーサーは最初の文字を生成します。次に、(>>=)最初のパーサーの結果を2番目の引数、つまり関数に渡します\x -> if p x then return x else failure。この関数は、入力ストリームの最初の文字について述部が満たされているかどうかをチェックします。それが満たされると、関数はreturn x入力を消費せずx、結果として単純に生成するパーサー()を生成します。述語を満たさない場合、関数はどの入力(failure)でも失敗するパーサーを生成します。

于 2012-09-29T13:26:11.563 に答える