Easy to use text parsing.
Describes an error during parsing, i.e. what caused a parser to fail, and at what position into the input text it failed.
Parse an input string using a specific parser, returning a result containing either the parsed value or an error.
parse "xyz" (char 'x') -- Ok 'x'
parse "xyz" (char 'w') -- Err { message = "expected char w", position = 0 }A parser that always succeeds with a specified value without reading any input.
parse "xyz" (succeed 42) -- Ok 42A parser that always fails with a specified error message without reading any input.
parse "xyz" (fail "nope") -- Err { message = "nope", position = 0 }In order to support self-referential parsers, you need to introduce lazy evaluation.
type Tree = Leaf | Node Tree Tree
tree : Parser Tree
tree =
oneOf [ leaf, node ]
leaf : Parser Tree
leaf =
map (always Leaf) (char 'x')
node : Parser Tree
node =
into Node
|> ignore (char '@')
|> grab (lazy (\_ -> tree))
|> grab (lazy (\_ -> tree))
parse "x" tree -- Ok Leaf
parse "@x@xx" tree -- Ok (Node Leaf (Node Leaf Leaf))Without lazy, this example would fail due to a circular reference.
Matches a specific string.
parse "hello world" (string "hello") -- Ok "hello"Matches a character if some predicate holds.
parse "123" (when Char.isDigit) -- Ok '1'Matches a character if the specified parser fails.
parse "xyz" (except (char 'a')) -- Ok 'x'
parse "xyz" (except (char 'x')) -- Err { message = "expected to not match", ... }A parser that simply reads a specific number of characters from the input.
parse "xyz" (chomp 2) -- Ok "xy"Matches one of a list of parsers.
parse "y" (oneOf [ char 'x', char 'y' ]) -- Ok 'y'Maybe match a value. If the parser succeeds with x, we'll succeed with
Just x. If if fails, we'll succeed with Nothing.
parse "42" (maybe int) -- Just 42
parse "hello" (maybe int) -- NothingMatches zero or more successive occurrences of a value. Succeeds with an empty list if there are no occurrences.
parse "xxy" (zeroOrMore (char 'x')) -- Ok [ 'x', 'x' ]
parse "yyy" (zeroOrMore (char 'x')) -- Ok []Matches one or more successive occurrences of a value. Fails if there are no occurrences.
parse "xxy" (oneOrMore (char 'x')) -- Ok [ 'x', 'x' ]
parse "yyy" (oneOrMore (char 'x')) -- Err { message = "expected char `x`", position = 0 }Matches a sequence of parsers in turn, succeeding with a list of their values if they all succeed.
parse "helloworld" (sequence [ string "hello", string "world" ]) -- Ok [ "hello", "world" ]Matches a specific number of occurrences of a parser, succeeding with a list of values.
parse "xxxx" (repeat 3 (char 'x')) -- Ok [ 'x', 'x', 'x' ]Matches zero or more values until a "stop" parser matches.
char '['
|> followedBy (until (char ']') anyChar)
|> parse "[abc]" -- Ok [ 'a', 'b', 'c' ]Create a parser that depends on the previous parser's result.
For example, you can support two different versions of a format if there's a version number included:
spec : Parser Spec
spec =
let
specByVersion version =
case version of
1 ->
v1
-- assume v1 is a Parser Spec
2 ->
v2
-- assume v2 is a Parser Spec
x ->
fail ("unknown spec version " ++ String.fromInt x)
in
string "version="
|> andThen specByVersionCreate a parser that depends on a previous parser succeeding. Unlike
andThen, this does not preserve the value of the first parser,
so it's only useful when you want to discard that value.
atMention : Parser String
atMention =
char '@'
|> followedBy usernameStart a parser pipeline that feeds values into a function.
Typically used to build up complex values.
type Operation = Binary Int Char Int
operation : Parser Operation
operation =
into Operation
|> grab int
|> ignore blanks
|> grab (oneOf [ char '+', char '-', char '*' ])
|> ignore blanks
|> grab int
parse "42 * 13" operation -- Binary 42 '*' 13Here we feed three values into Operation while ignoring blank characters between
the values.
Grabs a value and feeds it into a function in a pipeline.
See into.
Ignores a matched value, preserving the previous value in a pipeline.
See into.
Matches two parsers and combines the result.
map2 (\x y -> (x, y)) anyChar anyChar
|> parse "xy" -- Ok ('x', 'y')Use the specified error message when the parser fails.
string "</div>"
|> withError "expected closing tag"Turns a parser that returns a list of characters into a parser that returns a String.
parse "xyz" (stringWith (sequence [ char 'x', anyChar, char 'z' ])) -- Ok "xyz"Maps a parser to include all the matched input as a String.
matchedString (sequence [ word, string "@", word ])
|> parse "hello@world!" -- Ok "hello@world"Matches zero or more values separated by a specified parser.
separatedBy (char ',') int
|> parse "42,13,99" -- Ok [ 42, 13, 99 ]
A
Parser ais an instruction for how to take some input text and turn it into anavalue as an updated input text that has had some prefix removed.If a parser fails to turn the input into a value, it fails with
Error.