|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Aug 2002
Messaggi: 2518
|
[Haskell] Parser
Salve a tutti,
l'altro giorno sulla lezione dei parser mi sono letteralmente perso, forse anche per via delle slide della lezione molto stringate. Sapreste darmi qualche link o qualche dritta su cosa sono e come utilizzare i parser in Haskell ? Certamente so cos'è a grossi linee un parser, ma semplicemente non riesco a capire cosa sono e a cosa servono queste funzioni parser in Haskell. Ad esempio questo codice, sarebbe l'equivalente di un typdef del C? come lo dovrei interpretare? Codice:
type Parser a = String -> [(a,String)] Questa funzione qui, sopratutto il tipo, come va interpretata? Cioè qui "Parser" sembra più una funzione che un tipo. Ma allora Type a cosa serve? e la prima riga di qui sotto cosa fignifica? Oppure vuol significare di sostituire Char al posto di a nel tipo Parser? (e quindi sono una specie di java generics?) Codice:
item :: Parser Char
item = \inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)]
Codice:
Parser item "abc" Vi ringrazio in anticipo, guylmaster. Ultima modifica di guylmaster : 29-10-2011 alle 17:18. |
|
|
|
|
|
#2 | ||||||
|
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
http://book.realworldhaskell.org/read/using-parsec.html Quote:
Quote:
Quote:
Haskell e' un linguaggio funzionale in cui le funzioni sono "cittadini di serie A" al pari degli interi, delle stringe delle liste etc., per cui puoi usarli in tutti i contesti in cui puoi usare quest'ultimi. Quote:
Nel caso specifico tu dichiari che item prende come argomento un (Parser Char) ovvero non un qualsiasi Parser, ma solo quelli per i caratteri (ovvero: le funzioni String -> [(Char,String)]). Quote:
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
||||||
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Aug 2011
Messaggi: 672
|
Se vuoi puoi dare un'occhiata al mio Thread
http://www.hwupgrade.it/forum/showthread.php?t=2409634 |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Aug 2002
Messaggi: 2518
|
Quote:
|
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Aug 2002
Messaggi: 2518
|
Restringo la domanda, ovvero i dubbi:
- leggevo, nella definizione di parser il seguente codice: Codice:
> newtype Parser a = P (String -> [(a,String)]) Quindi per questo ho bisogno di una funzione parse per applicare una funzione di parser ad una stringa: Codice:
parse :: Parser a -> String -> [(a,String)] parse p inp = p inp Quindi detto in poche parole noi abbiamo sia Parse che parser solo per rendere più leggibile il codice? Ad esempio se prendiamo il parser item Codice:
item :: Parser Char
item = \inp -> case nip of
[] -> []
(x:xs) -> [(x,xs)]
Però a questo punto mi sfugge perchè per eseguirla devo darla in input alla funzione parse. Probabilmente (anzi sicuramente) mi sfugge l'esatto significato di: Codice:
> newtype Parser a = P (String -> [(a,String)]) Codice:
P (String -> [(a,String)]) Forse è che mi sfugge cos'è una monade e nelle slide viene detto che Parser è una monade, qualcuno saprebbe darmi una definizione semplice della cosa? |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Aug 2011
Messaggi: 672
|
Scusa prima di tutto mi diresti che libreria usi?
Io sto usando Parsec, che dovrebbe essere la più famosa per Haskell. Codice:
import Text.ParserCombinators.Parsec |
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Aug 2002
Messaggi: 2518
|
Quote:
http://www.cs.nott.ac.uk/~gmh/book.html la libreria è questa: http://www.cs.nott.ac.uk/~gmh/parser.lhs Ma ripeto sono poche righe di codice solo a scopo "di studio" però intanto così su due piedi mi sto perdendo. |
|
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Aug 2011
Messaggi: 672
|
Allora, intanto anch'io lo sto studiando in ambito accademico e sono molto MENO esperto di quanto pensi...
Quote:
Sinceramente non capisco a cosa serve esattamente.. Ma è diverso da quello che avevo scritto prima Codice:
type Parser a = String -> [(a,String)] Dove a è un parametro, ovvero può essere qualsiasi tipo. Ad esempio Codice:
item :: Parser Char Comunque nelle librerie che sto usando io (e penso possa farlo anche tu) il tipo Parser è già definito, non capisco perchè a te lo facciano definire.. |
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Aug 2011
Messaggi: 672
|
Quote:
Penso sia necessaria, anche io ne uso una (trovata in rete) Codice:
run :: Show a => Parser a -> String -> IO ()
run p input
= case (parse p "" input) of
Left err -> do{ putStr "parse error at "
; print err
}
Right x -> print x
|
|
|
|
|
|
|
#10 | |||||
|
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
In rispetto al codice precedente pero' in questo caso e' stato usato newtype e non type, per cui non e' come una typedef (e infatti hai a destra P (String -> [(a,String)]), Se hai un po' di esperienza di C e simili, consideralo qualcosa tipo una struct P con un singolo valore. In particolare questo vuol dire che le operazioni che prendono come argomento un (String -> [(A,String)]) non possono operare direttamente su un Parser a, a differenza di quanto accade col type di prima. Quote:
Funziona se usi la type. In quel caso Parser a non e' altro che un sinonimo di String ->[(a,String)] e parse e' solo scritta per leggibilita' (per uno poco abituato alla programmazione funzionale), in quanto se parse p inp e' uguale p inp tanto vale usare direttamente la seconda definizione. Con la newtype invece quello che dovrebbe compilarti e' il codice seguente: Codice:
parse :: Parser a -> String -> [(a,String)] parse (P p) inp = p inp Ovvero devi "tirare fuori" la funzione da Parser a con del pattern matching per poterla utilizzare. Ma il fatto di definire una funzione parse per fare questo e' solo una scelta di comodo. Quote:
Quote:
Se e' come penso allora item non e' altro che un particolare parser pensato per leggere caratteri (infatti legge un singolo carattere alla volta). Quote:
Quella riga dice che Parser a e' un nuovo tipo che e' costituito a sua volta da un singolo tipo preesistente (in questo caso una funzione). P e' un costruttore che serve per distinguerlo dal tipo contenuto: se f e' di tipo (String -> [(a,String)]), allora P f e' di tipo Parser a
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|||||
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 11:35.




















