-
-
Save mumuxme/56dd1d78a9503053033366fc4289df93 to your computer and use it in GitHub Desktop.
Parsing in Haskell (ghc 8.0)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Data.Char | |
| import Data.List | |
| type Parser s a = s -> Maybe (a, s) | |
| string :: String -> Parser String String | |
| string pat input = | |
| case stripPrefix pat input of | |
| Nothing -> Nothing | |
| Just rest -> Just (pat, rest) | |
| number :: Parser String Int | |
| number s = case reads hd of | |
| [(n, _)] -> Just (n, tl) | |
| _ -> Nothing | |
| where | |
| (hd, tl) = span isDigit s | |
| version :: Parser String (Int, Int) | |
| version s0 = | |
| case string "HTTP/" s0 of | |
| Nothing -> Nothing | |
| Just (_, s1) -> | |
| case number s1 of | |
| Nothing -> Nothing | |
| Just (maj, s2) -> | |
| case string "." s2 of | |
| Nothing -> Nothing | |
| Just (_, s3) -> | |
| case number s3 of | |
| Nothing -> Nothing | |
| Just (min, s4) -> Just ((maj, min), s4) | |
| andThen :: Parser s a -> (a -> Parser s b) -> Parser s b | |
| andThen parse next = \input -> | |
| case parse input of | |
| Nothing -> Nothing | |
| Just (a, input') -> next a input' | |
| version1 = | |
| string "HTTP/" `andThen` \_ -> | |
| number `andThen` \maj -> | |
| string "." `andThen` \_ -> | |
| number `andThen` \min -> | |
| \s -> Just ((maj, min), s) | |
| stuff :: a -> Parser s a | |
| stuff a = \s -> Just (a, s) | |
| version2 = | |
| string "HTTP/" `andThen` \_ -> | |
| number `andThen` \maj -> | |
| string "." `andThen` \_ -> | |
| number `andThen` \min -> | |
| stuff (maj, min) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Data.Char | |
| import Data.List | |
| import Control.Monad (ap) | |
| newtype Parser s a = P { runP :: s -> Maybe (a, s) } | |
| string :: String -> Parser String String | |
| string pat = P $ \input -> | |
| case stripPrefix pat input of | |
| Nothing -> Nothing | |
| Just rest -> Just (pat, rest) | |
| number :: Parser String Int | |
| number = P $ \s -> | |
| let | |
| (hd, tl) = span isDigit s | |
| in | |
| case reads hd of | |
| [(n, _)] -> Just (n, tl) | |
| _ -> Nothing | |
| shove :: a -> Parser s a | |
| shove a = P $ \input -> Just (a, input) | |
| bind :: Parser s a -> (a -> Parser s b) -> Parser s b | |
| bind parse next = P $ \input -> | |
| case runP parse input of | |
| Nothing -> Nothing | |
| Just (a, input') -> runP (next a) input' | |
| instance Functor (Parser s) where | |
| fmap f parser = P $ \input -> | |
| case runP parser input of | |
| Nothing -> Nothing | |
| Just (a, input') -> Just (f a, input') | |
| instance Applicative (Parser s) where | |
| pure = return | |
| (<*>) = ap | |
| instance Monad (Parser s) where | |
| (>>=) = bind | |
| return = shove | |
| version3 = do | |
| string "HTTP/" | |
| maj <- number | |
| string "." | |
| min <- number | |
| return (maj,min) | |
| version4 = (,) <$> | |
| (string "HTTP/" *> number <* string ".") <*> | |
| number | |
| (.*>) :: String -> Parser String b -> Parser String b | |
| a .*> b = string a *> b | |
| infixl 4 .*> | |
| (<*.) :: Parser String a -> String -> Parser String a | |
| a <*. b = a <* string b | |
| infixl 4 <*. | |
| version5 = (,) <$> ("HTTP/" .*> number <*. ".") | |
| <*> number |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Data.Char | |
| import Data.List | |
| import Control.Monad (liftM, ap) | |
| newtype Parser s a = P { runP :: s -> Maybe (a, s) } | |
| string :: String -> Parser String String | |
| string pat = P $ \input -> | |
| case stripPrefix pat input of | |
| Nothing -> Nothing | |
| Just rest -> Just (pat, rest) | |
| number :: Parser String Int | |
| number = P $ \s -> | |
| let | |
| (hd, tl) = span isDigit s | |
| in | |
| case reads hd of | |
| [(n, _)] -> Just (n, tl) | |
| _ -> Nothing | |
| shove :: a -> Parser s a | |
| shove a = P $ \input -> Just (a, input) | |
| bind :: Parser s a -> (a -> Parser s b) -> Parser s b | |
| bind parse next = P $ \input -> | |
| case runP parse input of | |
| Nothing -> Nothing | |
| Just (a, input') -> runP (next a) input' | |
| instance Monad (Parser s) where | |
| (>>=) = bind | |
| return = pure | |
| instance Applicative (Parser s) where | |
| pure = shove | |
| (<*>) = ap | |
| instance Functor (Parser s) where | |
| fmap = liftM | |
| version3 = do | |
| string "HTTP/" | |
| maj <- number | |
| string "." | |
| min <- number | |
| return (maj,min) | |
| version4 = (,) <$> | |
| (string "HTTP/" *> number <* string ".") <*> | |
| number | |
| (.*>) :: String -> Parser String b -> Parser String b | |
| a .*> b = string a *> b | |
| infixl 4 .*> | |
| (<*.) :: Parser String a -> String -> Parser String a | |
| a <*. b = a <* string b | |
| infixl 4 <*. | |
| version5 = (,) <$> ("HTTP/" .*> number <*. ".") | |
| <*> number |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment