This library provides a bunch of parser combinators and could be used for Web form validation.
It follows ideas described here: https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validateBy/
inp -> Result (Cons err) out
Parser type
inp Input type (what is parsed/validated) err Error type (Could be your custom error type) out Output type (Could be your domain type)
all : Cons (Parser inp err a) -> inp -> Result (Cons err) (Cons a)
Given a non-empty list of uniform parsers returns a parser that produces a non empty list of their results. If any of the provided parsers fails - resulting parser also fails.
andThen : Parser a err b -> Parser inp err a -> inp -> Result (Cons err) b
Parser composition: result produced by second parser is fed to the first
by : (inp1 -> inp0) -> Parser inp0 err out -> Parser inp1 err (out -> b) -> Parser inp1 err b
Useful for a "pipeline" style:
example : Parser { bar : String, baz : String } Error Foo
example =
succeed (\a b -> Foo a b)
|> by .bar parseBar
|> by .baz parseBaz
contramap : (inp1 -> inp0) -> Parser inp0 err out -> Parser inp1 err out
Maps over Parser input
fail : err -> Result (Cons err) out
Returns error
fromReader : (inp -> Maybe out) -> err -> Parser inp err out
Create Parser from function of type inp -> Maybe out
map : (out0 -> out1) -> Parser inp err out0 -> Parser inp err out1
Maps over parser result
mapError : (err0 -> err1) -> Parser inp err0 out -> Parser inp err1 out
Maps over parser error
merge : (a -> b -> c) -> Parser inp err a -> Parser inp err b -> inp -> Result (Cons err) c
When given a function that merges parsing results and two parsers producing such results - returns a parser that produces a result of that function.
ok : out -> Result (Cons err) out
Returns successfully parsed value
run : Parser input err out -> input -> Result (Cons err) out
Syntactic abstraction: applies parser to its input
succeed : out -> Parser input err out
Useful for a "pipeline" style:
example : Parser { bar : String, baz : String } Error Foo
example =
succeed (\a b -> Foo a b)
|> by .bar parseBar
|> by .baz parseBaz
|> validateBy identity barBazParser
validateBy : (inp1 -> inp0) -> Parser inp0 err () -> Parser inp1 err b -> Parser inp1 err b
Useful for a "pipeline" style when validator emits an error message but reurns () in order not to consume constructor argument:
example : Parser { bar: String, baz: String } Error Foo
example =
succeed (\bar baz -> Foo bar baz)
|> by .bar parseBar
|> by .baz parseBaz
|> validateBy identity barBazParser
barBazParser : { bar: String, baz: String } Error Unit
barBazParser { bar, baz } =
if bar /= baz
then Parser.fail "Bar != Baz"
else Parser.ok ()
fromPredicate : (inp -> Basics.Bool) -> err -> (inp -> out) -> inp -> Result (Cons err) out
Create Parser from predicate function that returns a wrapped input value. Parser fails with provided error in case if predicate evaluates to False.
zip : Parser inp err a -> Parser inp err b -> Parser inp err ( a, b )
Given 2 parsers, feeds same input into both of them and returns results as tuple
note : err -> Parser inp () out -> Parser inp err out
Given a parser without error decorates it with an error provided