Skip to content

Commit 27e5636

Browse files
committed
liftMaybe, liftEither, liftExceptT
#196
1 parent 2a49674 commit 27e5636

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

src/Parsing.purs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ module Parsing
2020
, fail
2121
, failWithPosition
2222
, region
23+
, liftMaybe
24+
, liftEither
25+
, liftExceptT
2326
, ParseState(..)
2427
, stateParserT
2528
, getParserT
@@ -33,6 +36,7 @@ import Control.Alt (class Alt)
3336
import Control.Apply (lift2)
3437
import Control.Lazy (class Lazy)
3538
import Control.Monad.Error.Class (class MonadError, class MonadThrow, catchError, throwError)
39+
import Control.Monad.Except (ExceptT, runExceptT)
3640
import Control.Monad.Reader.Class (class MonadAsk, class MonadReader, ask, local)
3741
import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM)
3842
import Control.Monad.State.Class (class MonadState, state)
@@ -43,6 +47,7 @@ import Data.Function.Uncurried (Fn2, Fn5, mkFn2, mkFn3, mkFn5, runFn2, runFn3, r
4347
import Data.Generic.Rep (class Generic)
4448
import Data.Identity (Identity)
4549
import Data.Lazy as Lazy
50+
import Data.Maybe (Maybe(..))
4651
import Data.Newtype (unwrap)
4752
import Data.Show.Generic (genericShow)
4853
import Data.Tuple (Tuple(..), fst)
@@ -441,4 +446,48 @@ instance Ord Position where
441446
-- |
442447
-- | `{ index: 0, line: 1, column: 1 }`
443448
initialPos :: Position
444-
initialPos = Position { index: 0, line: 1, column: 1 }
449+
initialPos = Position { index: 0, line: 1, column: 1 }
450+
451+
-- | Lift a `Maybe a` computation into a `ParserT`, with a note for
452+
-- | the `ParseError` message in case of `Nothing`.
453+
-- |
454+
-- | Consumes no parsing input, does not change the parser state at all.
455+
-- | If the `Maybe` computation is `Nothing`, then this will `fail` in the
456+
-- | `ParserT` monad with the given error message `String` at the current input
457+
-- | `Position`.
458+
-- |
459+
-- | This is a “validation” function, for when we want to produce some
460+
-- | data from the parsing input or fail at the current
461+
-- | parsing position if that’s impossible.
462+
liftMaybe :: forall s m a. Monad m => Lazy.Lazy String -> Maybe a -> ParserT s m a
463+
liftMaybe message f = case f of
464+
Nothing -> fail (Lazy.force message)
465+
Just x -> pure x
466+
467+
-- | Lift an `Either String a` computation into a `ParserT`.
468+
-- |
469+
-- | Consumes no parsing input, does not change the parser state at all.
470+
-- | If the `Either` computation is `Left String`, then this will `fail` in the
471+
-- | `ParserT` monad at the current input `Position`.
472+
-- |
473+
-- | This is a “validation” function, for when we want to produce some
474+
-- | data from the parsing input or fail at the current
475+
-- | parsing position if that’s impossible.
476+
liftEither :: forall s m a. Monad m => Either String a -> ParserT s m a
477+
liftEither f = case f of
478+
Left err -> fail err
479+
Right x -> pure x
480+
481+
-- | Lift an `ExceptT String m a` computation into a `ParserT`.
482+
-- |
483+
-- | Consumes no parsing input, does not change the parser state at all.
484+
-- | If the `ExceptT` computation is `Left String`, then this will `fail` in the
485+
-- | `ParserT` monad at the current input `Position`.
486+
-- |
487+
-- | This is a “validation” function, for when we want to produce some
488+
-- | data from the parsing input or fail at the current
489+
-- | parsing position if that’s impossible.
490+
liftExceptT :: forall s m a. (Monad m) => ExceptT String m a -> ParserT s m a
491+
liftExceptT f = lift (runExceptT f) >>= case _ of
492+
Left err -> fail err
493+
Right x -> pure x

0 commit comments

Comments
 (0)