Skip to content

Instantly share code, notes, and snippets.

@lambda-fairy
Created August 12, 2013 06:19
Show Gist options
  • Save lambda-fairy/6208613 to your computer and use it in GitHub Desktop.
Save lambda-fairy/6208613 to your computer and use it in GitHub Desktop.
Simple parser combinator library
-- | A simple parser combinator library.
module Text.Comb
( Parser(runParser)
, parse
, next
, satisfy
, match
, matches
) where
import Control.Applicative
import Control.Arrow (first)
import Control.Monad
newtype Parser i a = Parser { runParser :: [i] -> Maybe (a, [i]) }
instance Functor (Parser i) where
fmap f = Parser . (fmap (first f) .) . runParser
instance Applicative (Parser i) where
pure x = Parser $ \is -> Just (x, is)
pf <*> px = Parser $ \is -> do
(f, is' ) <- runParser pf is
(x, is'') <- runParser px is'
return (f x, is'')
instance Alternative (Parser i) where
empty = Parser $ \_ -> Nothing
p0 <|> p1 = Parser $ \is -> runParser p0 is <|> runParser p1 is
instance Monad (Parser i) where
return = pure
p >>= k = Parser $ \is -> do
(x, is') <- runParser p is
runParser (k x) is'
instance MonadPlus (Parser i) where
mzero = empty
mplus = (<|>)
parse :: Parser i a -> [i] -> Maybe a
parse p is = case runParser p is of
Just (x, []) -> Just x
_ -> Nothing
next :: Parser i i
next = Parser $ \is ->
case is of
[] -> Nothing
(i:is') -> Just (i, is')
satisfy :: (i -> Bool) -> Parser i i
satisfy p = do
i <- next
guard (p i)
return i
match :: Eq i => i -> Parser i i
match = satisfy . (==)
matches :: Eq i => [i] -> Parser i [i]
matches = mapM match
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment