Skip to content

Instantly share code, notes, and snippets.

@mumuxme
Last active January 7, 2017 05:43
Show Gist options
  • Select an option

  • Save mumuxme/56dd1d78a9503053033366fc4289df93 to your computer and use it in GitHub Desktop.

Select an option

Save mumuxme/56dd1d78a9503053033366fc4289df93 to your computer and use it in GitHub Desktop.
Parsing in Haskell (ghc 8.0)
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)
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
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