diff options
| author | Miguel <m.i@gmx.at> | 2019-03-19 19:24:07 +0100 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2019-03-19 19:24:07 +0100 |
| commit | 01fbd2efca79bd2369beb6308cb6665e4df58f38 (patch) | |
| tree | 7f999074a3eaadcef5c92117dd865f823a6972b5 /00_blog/00040_Haskell/00150_Applicative-vs-Monadic-Parsing | |
| parent | 2074edea81ea129085f451792b5ef601bbba46c2 (diff) | |
some minor beautifications
Diffstat (limited to '00_blog/00040_Haskell/00150_Applicative-vs-Monadic-Parsing')
| -rw-r--r-- | 00_blog/00040_Haskell/00150_Applicative-vs-Monadic-Parsing/index.md | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/00_blog/00040_Haskell/00150_Applicative-vs-Monadic-Parsing/index.md b/00_blog/00040_Haskell/00150_Applicative-vs-Monadic-Parsing/index.md index 800bab3..e57e084 100644 --- a/00_blog/00040_Haskell/00150_Applicative-vs-Monadic-Parsing/index.md +++ b/00_blog/00040_Haskell/00150_Applicative-vs-Monadic-Parsing/index.md @@ -90,17 +90,14 @@ instance Monad (Parser a) where where g inp = case parse p inp of Just (a,b) -> parse (f a) b _ -> Nothing -parse :: Parser a b -> a -> Maybe (b,a) -parse (Parser f) inp = f inp ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## Primitives We also need at least a minimal set of primitives to parse something. Note that the primitives can give you the effects of Applicative or -Alternative even if there's no instance (as dmwit pointed out on #haskell). -E.g. the _word_ primitive below, could not be composed, by combining the -_char_ parsers in an applicative style only. +Alternative even if the Parser itself is not an instance of these. +(Thanks to dmwit for pointing this out on #haskell). The _num_ parser makes use of the _some_ combinator which requires our Parser to be an instance of _Alternative_ as well. _Applicative_ @@ -108,11 +105,6 @@ alone is of limited use in practice since without it, we also lack the <|> combinator. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.haskell .numberLines} -word :: String -> Parser String String -word w = Parser g where l = length w - g inp = if take l inp == w then Just (w,drop l inp) - else Nothing - satisfy :: (Char -> Bool) -> Parser String Char satisfy f = Parser g where g (x:xs) | f x = Just (x,xs) g _ = Nothing @@ -128,13 +120,23 @@ notChar c = satisfy (/=c) num :: Parser String Int num = read <$> some (satisfy isDigit) + +word :: String -> Parser String String +word (c:cs) = (:) <$> char c <*> word cs +word _ = pure "" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## Applicative / Alternative parsing +Now we are able to parse any context free grammar, given our +_satisfy_ Parser along with Applicative, Alternative, and recursion. + Let's parse something! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.haskell .numberLines} +-- we parse, by simply applying the function encapsulated in our Parser on the input. +parse (Parser f) inp = f inp + -- well-formed parentheses are the canonical example of a context-free grammar parsePar = concat <$> some parseP where parseP = word "()" <|> (char '(' *> parsePar <* char ')') parse parsePar "((()())()())" @@ -180,3 +182,4 @@ As usual, use the simplest tool that will suffice :smile: * <http://dev.stephendiehl.com/fun/002_parsers.html> * <https://eli.thegreenplace.net/2017/deciphering-haskells-applicative-and-monadic-parsers/> * <https://byorgey.wordpress.com/2012/01/05/parsing-context-sensitive-languages-with-applicative/> +* <https://arunraghavan.net/2018/02/applicative-functors-for-fun-and-parsing/> |
