{-# LANGUAGE ConstraintKinds, GADTs, LambdaCase, RankNTypes #-} module Parser where import Control.Applicative import Control.Monad import Control.Selective -- See Section 7.2 of the paper: -- https://www.staff.ncl.ac.uk/andrey.mokhov/selective-functors.pdf newtype Parser a = Parser { parse :: String -> [(a, String)] } instance Functor Parser where fmap f p = Parser $ \x -> [ (f a, s) | (a, s) <- parse p x ] instance Applicative Parser where pure a = Parser $ \s -> [(a, s)] (<*>) = ap instance Alternative Parser where empty = Parser (const []) p <|> q = Parser $ \s -> parse p s ++ parse q s instance Selective Parser where select = selectM instance Monad Parser where return = pure p >>= f = Parser $ \x -> concat [ parse (f a) y | (a, y) <- parse p x ] class MonadZero f where zero :: f a instance MonadZero Parser where zero = Parser (const []) item :: Parser Char item = Parser $ \case "" -> [] (c:cs) -> [(c,cs)] sat :: (Char -> Bool) -> Parser Char sat p = do { c <- item; if p c then return c else zero } char :: Char -> Parser Char char c = sat (==c) string :: String -> Parser String string [] = return "" string (c:cs) = do _ <- char c _ <- string cs return (c:cs) bin :: Parser Int bin = undefined hex :: Parser Int hex = undefined numberA :: Parser Int numberA = (string "0b" *> bin) <|> (string "0x" *> hex) numberS :: Parser Int numberS = string "0" *> ifS (('b'==) <$> sat (`elem` "bx")) bin hex