Created
August 12, 2013 06:19
-
-
Save lambda-fairy/6208613 to your computer and use it in GitHub Desktop.
Simple parser combinator library
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
-- | 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