module PatchReadMonads (Stringalike(..), ParserM, work, maybe_work, alter_input, parse_strictly, parse_lazily, peek_input, lex_char, lex_string, lex_strings, lex_eof, my_lex) where import Stringalike ( Stringalike(..) ) lex_char :: (Stringalike s, ParserM m) => Char -> m s () lex_char c = lex_string [c] lex_string :: (Stringalike s, ParserM m) => String -> m s () lex_string str = work $ \s -> case my_lex s of Just (xs, ys) | sal_to_string xs == str -> Just ((), ys) _ -> Nothing lex_eof :: (Stringalike s, ParserM m) => m s () lex_eof = work $ \s -> if sal_null (sal_dropWhite s) then (Just ((), sal_empty)) else Nothing lex_strings :: (Stringalike s, ParserM m) => [String] -> m s String lex_strings str = work $ \s -> case my_lex s of Just (xs, ys) | xs' `elem` str -> Just (xs', ys) where xs' = sal_to_string xs _ -> Nothing my_lex :: Stringalike s => s -> Maybe (s, s) my_lex s = let s' = sal_dropWhite s in if sal_null s' then Nothing else Just $ sal_breakWhite s' alter_input :: (Stringalike s, ParserM m) => (s -> s) -> m s () alter_input f = work (\s -> Just ((), f s)) class ParserM m where work :: (s -> Maybe (a, s)) -> m s a maybe_work :: (s -> Maybe (a, s)) -> m s (Maybe a) peek_input :: m s s ----- Strict Monad ----- parse_strictly :: SM s a -> s -> Maybe (a, s) parse_strictly (SM f) s = f s newtype SM s a = SM (s -> Maybe (a, s)) instance Monad (SM s) where SM m >>= k = SM $ \s -> case m s of Nothing -> Nothing Just (x, s') -> case k x of SM y -> y s' return x = SM (\s -> Just (x,s)) fail _ = SM (\_ -> Nothing) instance ParserM SM where work f = SM f maybe_work f = SM $ \s -> case f s of Just (x, s') -> Just (Just x, s') Nothing -> Just (Nothing, s) peek_input = SM $ \s -> Just (s, s) ----- Lazy Monad ----- parse_lazily :: LM s a -> s -> (a, s) parse_lazily (LM f) s = f s newtype LM s a = LM (s -> (a, s)) instance Monad (LM s) where LM m >>= k = LM $ \s -> let (x, s') = m s LM y = k x in y s' return x = LM (\s -> (x,s)) fail s = error s instance ParserM LM where work f = LM $ \s -> case f s of Nothing -> error "parser error" Just x -> x maybe_work f = LM $ \s -> case f s of Nothing -> (Nothing, s) Just (x, s') -> (Just x, s') peek_input = LM $ \s -> (s, s)