-
Notifications
You must be signed in to change notification settings - Fork 51
Compactable
and Filterable
instances
#85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
5179d5a
32db7b4
faa71d5
b9ba84a
8a3c00d
664abda
66b2a6c
cd9bb37
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,9 @@ module Text.Parsing.Parser | |
, runParserT | ||
, hoistParserT | ||
, mapParserT | ||
, setConsumed | ||
, consume | ||
, unconsume | ||
, position | ||
, fail | ||
, failWithPosition | ||
|
@@ -23,11 +25,14 @@ import Control.Lazy (defer, class Lazy) | |
import Control.Monad.Error.Class (class MonadThrow, throwError) | ||
import Control.Monad.Except (class MonadError, ExceptT(..), runExceptT, mapExceptT) | ||
import Control.Monad.Rec.Class (class MonadRec) | ||
import Control.Monad.State (class MonadState, StateT(..), evalStateT, gets, mapStateT, modify_, runStateT) | ||
import Control.Monad.State (class MonadState, StateT(..), evalStateT, get, gets, put, mapStateT, modify_, runStateT) | ||
import Control.Monad.Trans.Class (class MonadTrans, lift) | ||
import Control.MonadPlus (class Alternative, class MonadZero, class MonadPlus, class Plus) | ||
import Data.Compactable (class Compactable) | ||
import Data.Either (Either(..)) | ||
import Data.Filterable (class Filterable) | ||
import Data.Identity (Identity) | ||
import Data.Maybe (Maybe(..)) | ||
import Data.Newtype (class Newtype, unwrap, over) | ||
import Data.Tuple (Tuple(..)) | ||
import Text.Parsing.Parser.Pos (Position, initialPos) | ||
|
@@ -120,10 +125,77 @@ instance monadPlusParserT :: Monad m => MonadPlus (ParserT s m) | |
instance monadTransParserT :: MonadTrans (ParserT s) where | ||
lift = ParserT <<< lift <<< lift | ||
|
||
instance compactableParserT :: Monad m => Compactable (ParserT s m) where | ||
compact p1 = do | ||
state <- get | ||
p1 >>= case _ of | ||
Just r -> pure r | ||
Nothing -> put state *> fail "Parse returned Nothing" | ||
separate p1 = | ||
{ left: do | ||
state <- get | ||
p1 >>= case _ of | ||
Left r -> pure r | ||
Right r -> put state *> fail "Parse returned Right" | ||
, right: do | ||
state <- get | ||
p1 >>= case _ of | ||
Left r -> put state *> fail "Parse returned Left" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here (and elsewhere) the { ...
, right: p1 >>= case _ of
Left _ -> do
state <- get
put state *> fail "Parse returned Left"
} For that matter, do you mind briefly letting me know the reason for getting and then putting the state? Is there any reason to not just call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The point in getting the state is that it's done before the parser |
||
Right r -> pure r | ||
} | ||
|
||
instance filterableParserT :: Monad m => Filterable (ParserT s m) where | ||
partitionMap pred p1 = | ||
{ left: do | ||
state <- get | ||
p1 <#> pred >>= case _ of | ||
Left r -> pure r | ||
Right r -> put state *> fail "Predicate returned Right" | ||
, right: do | ||
state <- get | ||
p1 <#> pred >>= case _ of | ||
Left r -> put state *> fail "Predicate returned Left" | ||
Right r -> pure r | ||
} | ||
partition pred p1 = | ||
{ yes: do | ||
state <- get | ||
r <- p1 | ||
case pred r of | ||
true -> pure r | ||
false -> put state *> fail "Result did not satisfy predicate" | ||
, no: do | ||
state <- get | ||
r <- p1 | ||
case pred r of | ||
true -> put state *> fail "Result unexpectedly satisfied predicate" | ||
false -> pure r | ||
} | ||
filterMap pred p1 = do | ||
state <- get | ||
p1 <#> pred >>= case _ of | ||
Just r -> pure r | ||
Nothing -> put state *> fail "Predicate returned Nothing" | ||
filter pred p1 = do | ||
state <- get | ||
r <- p1 | ||
case pred r of | ||
true -> pure r | ||
false -> put state *> fail "Result did not satisfy predicate" | ||
|
||
|
||
-- | Set or unset the consumed flag. | ||
setConsumed :: forall s m. Monad m => Boolean -> ParserT s m Unit | ||
setConsumed bool = modify_ \(ParseState input pos _) -> | ||
ParseState input pos bool | ||
|
||
-- | Set the consumed flag. | ||
consume :: forall s m. Monad m => ParserT s m Unit | ||
consume = modify_ \(ParseState input pos _) -> | ||
ParseState input pos true | ||
consume = setConsumed true | ||
|
||
-- | Unset the consumed flag. | ||
unconsume :: forall s m. Monad m => ParserT s m Unit | ||
unconsume = setConsumed false | ||
|
||
-- | Returns the current position in the stream. | ||
position :: forall s m. Monad m => ParserT s m Position | ||
|
Uh oh!
There was an error while loading. Please reload this page.