5

attoparsecはファイルを解析するために私に提案されました、今私はそれを使用する方法を理解しなければなりません。誰かが私にこのコードをくれました:

type Environment = M.Map String String 
import Data.Attoparsec (maybeResult)
import qualified Data.Attoparsec.Char8 as A
import qualified Data.ByteString.Char8 as B
environment :: A.Parser Environment
environment = M.fromList <$> A.sepBy entry A.endOfLine
parseEnvironment = maybeResult .flip A.feed B.empty . A.parse environment
spaces = A.many $ A.char ' '
entry = (,) <$> upTo ':' <*> upTo ';'
upTo delimiter = B.unpack <$> A.takeWhile (A.notInClass $ delimiter : " ")
                      <* (spaces >> A.char delimiter >> spaces)

これは非常にうまく機能しますが、理由はわかりません。フリップを使用する理由は何ですか。A.feedの引数を別の順序に並べるのは簡単ではありませんか。そしてなぜB.emptyがあるのですか?私が勉強できることについてのチュートリアルはありますか?前もって感謝します

4

1 に答える 1

6

この StackOverflow questionfeedへの回答に、 の必要性についての説明があります。Bryan O'Sullivan (Attoparsec の作成者) はそこで次のように述べています。

失敗する前にできるだけ多くの入力を消費する attoparsec パーサーを作成する場合、入力の最後に達したときに部分的な結果の継続を通知する必要があります。

これを行うには、空のバイト文字列をフィードします。

問題のコードを書いたことは認めますがpointfree、この場合は実際には使用しませんでした。ここでは単純な構成が理にかなっています。パーサーを実行し ( A.parse environment)、完了したことを伝え ( )、一種の基本的なエラー処理として にflip A.feed B.empty変換します( )。私の意見では、これは指摘されたバージョンよりもきれいに感じます:MaybemaybeResult

parseEnvironment b = maybeResult $ A.feed (A.parse environment b) B.empty

残りはかなり慣用的な applicative parsingだと思いますが、>>代わりにを使用した理由はわかりません*>

于 2010-08-27T16:33:28.257 に答える