@@ -5,6 +5,7 @@ import Prelude
5
5
import Data.Either
6
6
import Data.Maybe
7
7
import Data.Monoid
8
+ import Data.Tuple
8
9
9
10
import Control.Monad
10
11
import Control.Monad.Identity
@@ -24,55 +25,60 @@ instance errorParseError :: Error ParseError where
24
25
noMsg = ParseError { message: " " }
25
26
strMsg msg = ParseError { message: msg }
26
27
27
- data Consumed = Consumed Boolean
28
+ data ParserT s m a = ParserT ( s -> m { input :: s , result :: Either ParseError a , consumed :: Boolean } )
28
29
29
- runConsumed :: Consumed -> Boolean
30
- runConsumed (Consumed c) = c
31
-
32
- data ParserT s m a = ParserT (StateT s (StateT Consumed (ErrorT ParseError m )) a )
33
-
34
- unParserT :: forall m s a . ParserT s m a -> StateT s (StateT Consumed (ErrorT ParseError m )) a
30
+ unParserT :: forall m s a . ParserT s m a -> s -> m { input :: s , result :: Either ParseError a , consumed :: Boolean }
35
31
unParserT (ParserT p) = p
36
32
37
33
runParserT :: forall m s a . (Monad m ) => s -> ParserT s m a -> m (Either ParseError a )
38
- runParserT s = runErrorT <<< flip evalStateT (Consumed false) <<< flip evalStateT s <<< unParserT
34
+ runParserT s p = do
35
+ o <- unParserT p s
36
+ return o. result
39
37
40
38
type Parser s a = ParserT s Identity a
41
39
42
40
runParser :: forall s a . s -> Parser s a -> Either ParseError a
43
41
runParser s = runIdentity <<< runParserT s
44
42
45
- instance functorParserT :: (Monad m ) => Functor (ParserT s m ) where
46
- (<$>) = liftA1
43
+ instance functorParserT :: (Functor m ) => Functor (ParserT s m ) where
44
+ (<$>) f p = ParserT $ \ s -> f' <$> unParserT p s
45
+ where
46
+ f' o = { input: o. input, result: f <$> o. result, consumed: o. consumed }
47
47
48
48
instance applyParserT :: (Monad m ) => Apply (ParserT s m ) where
49
49
(<*>) = ap
50
50
51
51
instance applicativeParserT :: (Monad m ) => Applicative (ParserT s m ) where
52
- pure a = ParserT ( pure a)
52
+ pure a = ParserT $ \ s -> pure { input : s, result : Right a, consumed : false }
53
53
54
54
instance alternativeParserT :: (Monad m ) => Alternative (ParserT s m ) where
55
- empty = ParserT empty
56
- (<|>) p1 p2 = ParserT (unParserT p1 <|> unParserT p2)
55
+ empty = fail " No alternative"
56
+ (<|>) p1 p2 = ParserT $ \ s -> unParserT p1 s >>= \ o ->
57
+ case o. result of
58
+ Left _ | not o. consumed -> unParserT p2 s
59
+ _ -> return o
57
60
58
61
instance bindParserT :: (Monad m ) => Bind (ParserT s m ) where
59
- (>>=) p f = ParserT (unParserT p >>= (unParserT <<< f))
62
+ (>>=) p f = ParserT $ \ s -> unParserT p s >>= \ o ->
63
+ case o. result of
64
+ Left err -> return { input: o. input, result: Left err, consumed: o. consumed }
65
+ Right a -> updateConsumedFlag o. consumed <$> unParserT (f a) o. input
66
+ where
67
+ updateConsumedFlag c o = { input: o. input, consumed: c || o. consumed, result: o. result }
60
68
61
69
instance monadParserT :: (Monad m ) => Monad (ParserT s m )
62
70
63
71
instance monadTransParserT :: MonadTrans (ParserT s ) where
64
- lift m = ParserT (lift (lift (lift m)))
65
-
66
- instance monadErrorParserT :: (Monad m ) => MonadError ParseError (ParserT s m ) where
67
- throwError e = ParserT (throwError e)
68
- catchError p f = ParserT (catchError (unParserT p) (unParserT <<< f))
72
+ lift m = ParserT $ \ s -> (\ a -> { input: s, consumed: false, result: Right a }) <$> m
69
73
70
74
instance monadStateParserT :: (Monad m ) => MonadState s (ParserT s m ) where
71
- state f = ParserT (state f)
75
+ state f = ParserT $ \ s ->
76
+ return $ case f s of
77
+ Tuple a s' -> { input: s', consumed: false, result: Right a }
72
78
73
- instance monadStateConsumerParserT :: (Monad m ) => MonadState Consumed ( ParserT s m ) where
74
- state f = ParserT (state f)
79
+ consume :: forall s m . (Monad m ) => ParserT s m {}
80
+ consume = ParserT $ \ s -> return { consumed : true, input : s, result : Right {} }
75
81
76
82
fail :: forall m s a . (Monad m ) => String -> ParserT s m a
77
- fail message = throwError (ParseError { message: message })
83
+ fail message = ParserT $ \ s -> return { input : s, consumed : false, result : Left (ParseError { message: message }) }
78
84
0 commit comments