|
|
|
|
|
by tel
5534 days ago
|
|
I think this might be some of the most beautiful code I've seen in a long while value :: Parser Value
value =
List <$> (char8 '(' *> sepBy value (takeWhile1 isSpace_w8) <* char8 ')')
<|> Number . fst . fromJust . B.readInteger <$> takeWhile1 isDigit_w8
<|> Symbol <$> takeWhile1 (inClass "A-Za-z\\-")
The power of parser combinators representing the elegant lisp syntax. |
|
Now, I know that Hoogle exists, so I'm able to look these things up, but it's pretty tough to untangle. Particularly when searching for
I found something that reads "This module describes a structure intermediate between a functor and a monad: it provides pure expressions and sequencing, but no binding. (Technically, a strong lax monoidal functor.)" Which is so full of jargon, my head hurts. And I even know what most of that jargon means!So as far as I can tell, here's what's going on....
Defines a grammar production using the left argument as a constructor on the matched value of the right argument. Separates productions as alternatives; in a PEG Grammer style. Both the <$> and <|> operators combine functions to result in a big master function that takes input and has the result type that is the big `one of A, B, C` algebraic type that is defined earlier: "Value". Matches a literal character (passed as an argument). Reads a parenthesis and throws it out of the result set. Similar for the close parenthesis later on. Produces a parser that consumes whitespace. Combines to produce a parser which reads a list of values (recursive here) and presumably eliminates the separators from the result. Similar story, reads an integer. Is a composed constructor that may or may not parse an integer, forcibly assumes it will succeed to parse one (which we know because we're reading digits). That integer parse stops when it hits a non-digit, and the unconsumed characters are returned as the second element of a tuple, so we call fst to take the first element of the tuple, discarding the unread characters (the main parser will consume those). Similar story again to the whitespace and numbers.OK, yeah, so.... amazing. Incredibly brilliant little bit of code. But holy hell was that tough to read. And I have no idea if I'd be able to write it in only a few hours. I'm far from certain I'd ever learn to write it as fast or faster than something more verbose.
Please let me know if I've misunderstood something....