سؤال

تم اقتراح 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 في الإجابات هذا السؤال stackoverflow. كما يقول برايان أوسوليفان (منشئ Attoparsec) هناك:

إذا كتبت محللًا من Attoparsec يستهلك أكبر قدر ممكن من المدخلات قبل الفشل ، فيجب عليك معرفة استمرار النتيجة الجزئية عندما تصل إلى نهاية المدخلات الخاصة بك.

يمكنك القيام بذلك عن طريق إطعامه بايت فارغ.

سأعترف أنني كتبت الرمز المعني ، ولم أستخدمها بالفعل pointfree في هذه الحالة. التكوين البسيط منطقي بالنسبة لي هنا: أنت تدير المحلل (A.parse environment) ، تخبرها أنك انتهيت (flip A.feed B.empty) ، وأنت تتحول إلى أ Maybe كنوع من معالجة الأخطاء الأساسية (maybeResult). في رأيي هذا أكثر نظافة من النسخة المدببة:

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

الباقي هو أعتقد أن الاصطلاحية إلى حد ما التحليل التطبيقي, ، على الرغم من أنني لست متأكدًا من سبب استخدامي >> بدلاً من *>.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top