mi piacerebbe scrivere
integer :: Parser Integer
integer = read <$ many1 space <*> many1 digit
C'è un gruppo di sinistra associativa (come l'applicazione) gli operatori parser-building <$>
, <*>
, <$
, <*
. La cosa nell'estrema sinistra dovrebbe essere la pura funzione che assembla il valore del risultato dai valori del componente. La cosa a destra di ogni operatore dovrebbe essere un parser, collettivamente dando i componenti della grammatica da sinistra a destra. Quale operatore utilizzare dipende da due scelte, come segue.
the thing to the right is signal/noise
_________________________
the thing to the left is \
+-------------------
pure/| <$> <$
a parser | <*> <*
Quindi, avendo scelto read :: String -> Integer
come pura funzione che sta per consegnare la semantica del parser, possiamo classificare lo spazio iniziale come "rumore" e il mazzo di cifre come "segnale", quindi
read <$ many1 space <*> many1 digit
(..) (.........) (.........)
pure noise parser |
(.................) |
parser signal parser
(.................................)
parser
È possibile combinare più possibilità con
p1 <|> ... <|> pn
e impossibilità express con
empty
È raramente necessario assegnare un nome ai componenti nei parser e il codice risultante assomiglia più a una grammatica con semantica aggiunta.
Perché il 'const'? – MathematicalOrchid
Vogliamo ignorare il valore (ma non l'effetto) di 'many1 space', e applicare' read' al valore di 'many1 digit'. (Scusa, sono appena entrato, è tardi, sono stanco: sto giocando veloce e sciolto con la terminologia.) Se immagini 's' e' d' rappresentano i valori di 'many1 space' e' many1 digit' rispettivamente, quindi il valore (ignorando gli effetti) di 'const read <$> many1 space <*> many1 digit' è' const read sd' = 'read d'. – dave4420