質問

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)

それは非常にうまく機能しますが、理由はわかりません。フリップを使用する理由は何ですか。そして、なぜb.emptyがあるのですか?勉強できるというチュートリアルはありますか?前もって感謝します

役に立ちましたか?

解決

必要性の説明があります feed の答えで このスタックフローの質問. 。 Bryan O'Sullivan(Attoparsecの作成者)が言うように:

故障する前にできるだけ多くの入力を消費するattoparsecパーサーを書く場合は、入力の終了に到達したときに部分的な結果の継続を伝える必要があります。

これを行うことができます。これは、空のバイテストリングを提供することで行うことができます。

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

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

残りはかなり慣用的だと思います アプリケーション解析, 、なぜ私が使用したのかわかりませんが >> それ以外の *>.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top