würde ich
integer :: Parser Integer
integer = read <$ many1 space <*> many1 digit
Es gibt eine Reihe von links assoziativ (wie Anwendung) Parser-Gebäudebetreiber <$>
, <*>
, <$
, <*
schreiben. Das Ding ganz links sollte die reine Funktion sein, die den Ergebniswert aus den Komponentenwerten zusammensetzt. Die Sache rechts von jedem Operator sollte ein Parser sein, der zusammen die Komponenten der Grammatik von links nach rechts gibt. Welcher Operator verwendet wird, hängt von zwei Möglichkeiten ab, wie folgt.
the thing to the right is signal/noise
_________________________
the thing to the left is \
+-------------------
pure/| <$> <$
a parser | <*> <*
So read :: String -> Integer
als reine Funktion gewählt zu haben, die die Semantik des Parsers liefern wird, können wir den führenden Platz als „Rauschen“ und das Bündel von Ziffern als „Signal“ klassifizieren, daher
read <$ many1 space <*> many1 digit
(..) (.........) (.........)
pure noise parser |
(.................) |
parser signal parser
(.................................)
parser
Sie können mit mehreren Möglichkeiten kombinieren
p1 <|> ... <|> pn
und Express Unmöglichkeit mit
empty
Es ist selten notwendig, Komponenten in Parsern zu benennen, und der resultierende Code sieht eher wie eine Grammatik mit hinzugefügter Semantik aus.
Warum die 'const'? – MathematicalOrchid
Wir wollen den Wert (aber nicht den Effekt) von 'many1 space' ignorieren und' read' auf den Wert von 'many1 digit' anwenden. (Sorry, ich bin gerade erst reingekommen, es ist spät, ich bin müde: Ich spiele schnell und locker mit der Terminologie.) Wenn Sie sich vorstellen, 's' und' d' repräsentieren die Werte von 'many1 space' und' many1 digit', dann ist der Wert (Ignoriereffekte) von 'const read <$> many1 space <*> many1 digit' ist 'const read sd' = 'read d'. – dave4420