2011-11-08 10 views
10
Iが使用Parsecのコンビネータの多くは、次のようなタイプのものである

はParsecのモナドを基礎

foo :: CharParser st Foo 

CharParserはとしてhere定義される:

type CharParser st = GenParser Char st 

CharParserこうしてGenParserを含むタイプの同義語であり、それ自体をhereを以下のように定義する:

type GenParser tok st = Parsec [tok] st 

GenParser次いでParsecを使用して割り当てられた別のタイプの同義語は、としてhere定義される:だからParsecはの部分的なアプリケーションであり、それ自体がタイプとhereを列挙し

type Parsec s u = ParsecT s u Identity 

data ParsecT s u m a 

単語と共に:

"ParsecT sumaはst連鎖型s、ユーザ状態型u、 の基礎となるモナドmと戻り値型a。

基礎となるモナドとは何ですか?特に、私がCharParserパーサを使用すると、それは何ですか?スタックにどこに挿入されているのか分かりません。あいまいなパーサーから成功した複数のパーズを返すために、Monadic Parsing in Haskellのリストモナドを使用することと関係はありますか?

答えて

6

GenParserは、Parsecで定義され、ParsecTでは定義されません。順番にパーセクはそう答えはCharParserを使用するときに根本的なモナドは、Identityモナドであるということです

type Parsec s u = ParsecT s u Identity 

として定義されます。

+1

ありがとう、私はそのステップを含めるために私の質問を編集しました。モナド変圧器のベースです。 Hutton/Meijerの論文で説明されているあいまいな解析とは関係がないと私は信じています。それで、リストモナドの使用は、Parsecパーサー内のどこにでも現れますか? Parsecはあいまいではありませんか?もしそうなら、 'Maybe'または' Either'を使ってコード化されていますか? – user2023370

+1

基礎となるモナドは、それ自体では使用されないので、あいまいさには影響しません。 – augustss

+0

私が尋ねようとしていたのは、Hutton/Meijer紙のリストモナドとの関係でした。 [Consumed](http://hackage.haskell.org/packages/archive/parsec/latest/doc/html/Text-Parsec-Prim.html#t:Consumed)および[Reply](http:// hackage .haskell.org/packages/archive/parsec/latest/doc/html/Text-Parsec-Prim.html#t:Reply)の形式をParsecで使用します。 – user2023370

7

あなたの場合、基礎となるモナドはIdentityです。しかし、ParsecTは、タイプパラメータmがない場合でも、Monadクラスのインスタンスであるという点で、ほとんどのモナドトランスと異なります。ソースコードを見ると、インスタンス宣言に "(Monad m) =>"がないことがわかります。

それでは、「私が重要でないモナドのスタックを持っていたら、どこで使うのですか?

その質問への回答の3があります:unconssを取ること

class (Monad m) => Stream s m t | s -> t where 
    uncons :: s -> m (Maybe (t,s)) 

お知らせ(ストリーム:それはストリームのうち次のトークンunconsに使用されている

  1. は、トークンt)を返し、モナドにラップされた結果を返します。これにより、次のトークンを取得するプロセス中に、またはそのプロセス中に面白いことを行うことができます。

  2. これは、各パーサーの出力結果で使用されます。つまり、入力には触れず、基になるモナドでアクションを実行し、コンバイナを使用してパーザを通常のパーサにバインドするパーサを作成できます。つまり、lift (x :: m a) :: ParsecT s u m aです。

  3. 最後に、RunParsecTとフレンドの最終結果(mIdentityに置き換えられるまでビルド)は、このモナドにラップされた結果を返します。

このモナドとMonadic Parsing in Haskellから1の間の関係はありません。この場合、HuttonとMeijerはParsecT自体のモナドインスタンスを参照しています。 Parsec-3.0.0以降でParsecTが基礎となるモナドを持つモナド変換器になったという事実は、この論文とは関係ありません。

しかし私があなたが探していると思うのは、可能な結果のリストがどこにあるかです。 HuttonとMeijerでは、パーサはすべての可能な結果のリストを返しますが、Parsecは1つだけを頑なに返します。私はあなたが結果でmを見ていると思うし、結果のリストがどこかに隠れていなければならないとあなた自身に考えていると思う。そうではない。

効率性の理由から、ParsecはHuttonとMeijerの結果リストで最初の一致結果を優先するように選択しました。これは、HuttonとMeijerのリストの末尾にある未使用の結果とトークンのストリームの前部の両方に、未使用の結果を投げ捨てることにします。 parsecでは、結合パーサーa <|> bを指定すると、aが入力を消費する場合、bは評価されません。これを回避する方法はtryです。aが失敗した場合は、状態を0にリセットしてからbを評価します。

MaybeまたはEitherを使用してコメントが尋ねられました。答えは「ほぼだけどかなりです」です。ローレベルのrun*関数を見ると、天気の入力が消費されたことを伝える代数型が返され、結果またはエラーメッセージを与える秒が表示されます。これらのタイプはEitherのように動作しますが、それらは直接使用されません。むしろこれをさらに伸ばして、アントワーヌ・ラッターのthe postに紹介します。これは、この仕組みがどのように機能し、なぜこのように行われるのかを説明します。