Podpis typ dla *>
mówi, że zwraca wynik z drugim parsera i wyrzuca wynik z pierwszej parsera. Tak więc email
zwraca tylko wynik ostatniego parsera w sekwencji.
Co prawdopodobnie chcesz coś bardziej jak
email =
stitch
<$> many1 alphaNum
<*> char '@'
<*> many1 alphaNum
<*> string ".com"
ten biegnie cztery parser i przekazuje wynik każdego jako argument stitch
. Jeśli piszesz odpowiednią implementację stitch
:
stitch a b c d = a ++ [b] ++ C++ d
następnie należy wrócić swój ciąg.
Zauważ, że w tym momencie, można również umieścić nazwę użytkownika i domenę do oddzielnych pól struktury danych czy coś:
data Email = Email {username, domain :: String}
email =
Email
<$> many1 alphaNum
<* char '@'
<*> ((++) <$> many1 alphaNum <*> string ".com")
Teraz twój parser zwraca strukturę Email
raczej niż tylko zwykłym sznurkiem. To może nie być to, czego szukasz, ale pokazuje, jak napisać bardziej wyrafinowany analizator składni.
Wszystko to używa interfejsu Applicative
do Parsetu, który jest ogólnie uważany za dobry styl. inne sposobem korzystania parsec jest interfejs Monad
:
email = do
a <- many1 alphaNum
b <- char '@'
c <- many1 alphaNum
d <- string ".com"
return (a ++ [b] ++ C++ d)
Czy to idiomatyczne drogą do osiągnięcia powiedział zadanie? Nie będę używać kodu w produkcji gdziekolwiek. Po prostu próbuję nauczyć się parsetu. – Jay
Oba sposoby są idiomatyczne – nponeccop