Skip to content

Instantly share code, notes, and snippets.

@pedrofurla
Last active January 3, 2016 23:19
Show Gist options
  • Select an option

  • Save pedrofurla/8534304 to your computer and use it in GitHub Desktop.

Select an option

Save pedrofurla/8534304 to your computer and use it in GitHub Desktop.
Some convenience combinators for Parser.hs and personParser. Suggestions and critiques are welcome.
sequenceParser ::
List (Parser a)
-> Parser (List a)
sequenceParser ps =
let
in foldRight (~~<) (valueParser Nil) ps
-- combinators for easily "appending" parsers
(~~<) :: Parser t -> Parser (List t) -> Parser (List t)
l ~~< r = bindParser (\c -> bindParser (\as -> valueParser (c :. as)) r) l
(~~~) :: Parser t -> Parser t -> Parser (List t)
l ~~~ r = l ~~< ( r ~~< valueParser Nil )
(>~~) :: Parser (List t) -> Parser t -> Parser (List t)
l >~~ r = l >~< (r ~~< valueParser Nil)
(>~<) :: Parser (List t) -> Parser (List t) -> Parser (List t)
l >~< r = bindParser (\cs -> bindParser (\as -> valueParser (cs ++ as)) r) l
-- The person parser. Basically it constructs a Parser (List (Person -> Person)) and applies each (Person -> Person) to the
-- parsed value.
personParser ::
Parser Person
personParser =
let
emptyPerson = Person {age = 0, firstName = "", surname = "", gender = 'x', phone = ""}
-- given a list of "transformations" from Person to Person apply these to the empty person
-- untimately arriving in a filled person
applyUpdates :: List (Person -> Person) -> Person
applyUpdates = foldRight ($) emptyPerson
-- some semi-lenses for the rescue
updAge a p = p { age = a }
updName a p = p { firstName = a }
updSurname a p = p { surname = a }
updGender a p = p { gender = a }
updPhone a p = p { phone = a }
pParser :: (a -> Person -> Person) -> Parser a -> Parser (Person -> Person)
pParser upd parser = bindParser (valueParser . upd) parser
-- see the usage of the "appending" combinators. Not need for sequencing.
pList :: Parser (List (Person -> Person))
pList =
pParser updAge ageParser
~~~
(space >>> pParser updName firstNameParser )
>~~
(space >>> pParser updSurname surnameParser)
>~~
(space >>> pParser updGender genderParser)
>~~
(space >>> pParser updPhone phoneParser)
in
bindParser (\pps -> valueParser $ applyUpdates pps) pList
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment