| Copyright | Dennis Gosnell 2019 |
|---|---|
| License | BSD3 |
| Maintainer | Dennis Gosnell (cdep.illabout@gmail.com) |
| Stability | experimental |
| Portability | unknown |
| Safe Haskell | None |
| Language | Haskell2010 |
Servant.Checked.Exceptions.Internal.EnvelopeT
Description
Synopsis
- data EnvelopeT es m a = EnvelopeT {
- runEnvelopeT :: m (Envelope es a)
- pureSuccEnvT :: Applicative m => a -> EnvelopeT es m a
- throwErrEnvT :: (Applicative m, IsMember e es) => e -> EnvelopeT es m a
- envelopeT :: Monad m => (OpenUnion es -> m c) -> (a -> m c) -> EnvelopeT es m a -> m c
- fromEnvT :: Monad m => (OpenUnion es -> m a) -> EnvelopeT es m a -> m a
- fromEnvTOr :: Monad m => EnvelopeT es m a -> (OpenUnion es -> m a) -> m a
- errEnvTMatch :: forall e es m a. (Functor m, IsMember e es) => EnvelopeT es m a -> m (Maybe e)
- catchesEnvT :: forall tuple es m a x. (Monad m, ToOpenProduct tuple (ReturnX (m x) es)) => tuple -> (a -> m x) -> EnvelopeT es m a -> m x
- envTToExceptT :: Functor m => EnvelopeT es m a -> ExceptT (OpenUnion es) m a
- exceptTToEnvT :: Functor m => ExceptT (OpenUnion es) m a -> EnvelopeT es m a
- emptyEnvT :: Functor m => EnvelopeT '[] m a -> m a
- relaxEnvT :: (Functor m, Contains es1 es2) => EnvelopeT es1 m a -> EnvelopeT es2 m a
- liftA2EnvT :: (Contains es1 fullEs, Contains es2 fullEs, Applicative m) => (a -> b -> c) -> EnvelopeT es1 m a -> EnvelopeT es2 m b -> EnvelopeT fullEs m c
- bindEnvT :: (Contains es1 fullEs, Contains es2 fullEs, Monad m) => EnvelopeT es1 m a -> (a -> EnvelopeT es2 m b) -> EnvelopeT fullEs m b
- envTRemove :: forall e es m a. (ElemRemove e es, Functor m) => EnvelopeT es m a -> EnvelopeT (Remove e es) m (Either a e)
Documentation
>>>:set -XDataKinds>>>:set -XTypeOperators>>>import Data.Functor.Identity (Identity(Identity))
data EnvelopeT es m a Source #
Constructors
| EnvelopeT | |
Fields
| |
Instances
pureSuccEnvT :: Applicative m => a -> EnvelopeT es m a Source #
throwErrEnvT :: (Applicative m, IsMember e es) => e -> EnvelopeT es m a Source #
Throw an error in an ErrEnvelope.
>>>let double = 3.5 :: Double>>>throwErrEnvT double :: EnvelopeT '[String, Double, Int] Identity ()EnvelopeT (Identity (ErrEnvelope (Identity 3.5)))
This is similar to throwError, but is specialized so you can throw just
one of the error types.
envelopeT :: Monad m => (OpenUnion es -> m c) -> (a -> m c) -> EnvelopeT es m a -> m c Source #
Case analysis for EnvelopeT.
Examples
Here is an example of matching on a SuccEnvelope:
>>>let env = pure "hello" :: EnvelopeT '[Double, Int] Identity String>>>envelopeT (\_ -> Identity "not a String") Identity envIdentity "hello"
Here is an example of matching on a ErrEnvelope:
>>>let double = 3.5 :: Double>>>let env' = throwErrEnvT double :: EnvelopeT '[Double, Int] Identity String>>>envelopeT (\_ -> Identity "not a String") Identity env'Identity "not a String"
fromEnvT :: Monad m => (OpenUnion es -> m a) -> EnvelopeT es m a -> m a Source #
Slight simplification of envelopeT.
Examples
Here is an example of successfully matching:
>>>let env = pure "hello" :: EnvelopeT '[Double, Int] Identity String>>>fromEnvT (\_ -> Identity "not a String") envIdentity "hello"
Here is an example of unsuccessfully matching:
>>>let double = 3.5 :: Double>>>let env' = throwErrEnvT double :: EnvelopeT '[Double, Int] Identity String>>>fromEnvT (\_ -> Identity "not a String") env'Identity "not a String"
fromEnvTOr :: Monad m => EnvelopeT es m a -> (OpenUnion es -> m a) -> m a Source #
Flipped version of fromEnvT.
errEnvTMatch :: forall e es m a. (Functor m, IsMember e es) => EnvelopeT es m a -> m (Maybe e) Source #
Try to pull out a specific e from an ErrEnvelope.
Examples
Successfully pull out an e:
>>>let double = 3.5 :: Double>>>let env = throwErrEnvT double :: EnvelopeT '[Double, Char] Identity ()>>>errEnvTMatch env :: Identity (Maybe Double)Identity (Just 3.5)
Unsuccessfully pull out an e:
>>>let env' = pure () :: EnvelopeT '[String, Double] Identity ()>>>errEnvTMatch env' :: Identity (Maybe Double)Identity Nothing
catchesEnvT :: forall tuple es m a x. (Monad m, ToOpenProduct tuple (ReturnX (m x) es)) => tuple -> (a -> m x) -> EnvelopeT es m a -> m x Source #
An alternate case anaylsis for an EnvelopeT. This method uses a tuple
containing handlers for each potential value of the underlying Envelope.
This is somewhat similar to the catches function.
When working with an Envelope with a large number of possible error types,
it can be easier to use catchesEnvT than envelopeT.
Examples
Here is an example of handling an SuccEnvelope with two possible error values.
Notice that a normal tuple is used:
>>>let env = pure 2.0 :: EnvelopeT '[Int, String] IO Double>>>let intHandler = (\int -> pure $ show int) :: Int -> IO String>>>let strHandler = (\str -> pure str) :: String -> IO String>>>let succHandler = (\dbl -> pure "got a double") :: Double -> IO String>>>catchesEnvT (intHandler, strHandler) succHandler env :: IO String"got a double"
Here is an example of handling an ErrEnvelope with two possible error values.
Notice that a normal tuple is used to hold the handlers:
>>>let env = throwErrEnvT (3 :: Int) :: EnvelopeT '[Int, String] Identity Double>>>let intHandler = (\int -> Identity $ show int) :: Int -> Identity String>>>let strHandler = (\str -> Identity str) :: String -> Identity String>>>let succHandler = (\dbl -> Identity "got a double") :: Double -> Identity String>>>catchesEnvT (intHandler, strHandler) succHandler env :: Identity StringIdentity "3"
Given an EnvelopeT like ,
the type of EnvelopeT '[Int, String] IO DoublecatchesEnvT becomes the following:
catchesEnvT:: (Int->IOx,String->IOx) -> (Double->IOx) ->EnvelopeT'[Int,String]IODouble->IOx
Here is an example of handling an ErrEnvelope with three possible values.
Notice how a 3-tuple is used to hold the handlers:
>>>let env = throwErrEnvT ("hi" :: String) :: EnvelopeT '[Int, String, Char] IO Double>>>let intHandler = (\int -> pure $ show int) :: Int -> IO String>>>let strHandler = (\str -> pure str) :: String -> IO String>>>let chrHandler = (\chr -> pure [chr]) :: Char -> IO String>>>let succHandler = (\dbl -> pure "got a double") :: Double -> IO String>>>catchesEnvT (intHandler, strHandler, chrHandler) succHandler env :: IO String"hi"
Given an Envelope like ,
the type of EnvelopeT '[Int, String, Char] IO DoublecatchesEnvT becomes the following:
catchesEnvT:: (Int->IOx,String->IOx,Char->IOx) -> (Double->IOx) ->EnvelopeT'[Int,String,Char]IODouble-> x
emptyEnvT :: Functor m => EnvelopeT '[] m a -> m a Source #
Safely unwrap an EnvelopeT.
>>>let myenvT = pure "hello" :: EnvelopeT '[] IO String>>>emptyEnvT myenvT :: IO String"hello"
relaxEnvT :: (Functor m, Contains es1 es2) => EnvelopeT es1 m a -> EnvelopeT es2 m a Source #
Change the errors type in an EnvelopeT to a larger set.
Examples
>>>let double = 3.5 :: Double>>>let envT1 = throwErrEnvT double :: EnvelopeT '[Int, Double] Identity Float>>>relaxEnvT envT1 :: EnvelopeT '[Char, Int, String, Double] Identity FloatEnvelopeT (Identity (ErrEnvelope (Identity 3.5)))
>>>let envT2 = pure double :: EnvelopeT '[Char, Int] Identity Double>>>relaxEnvT envT2 :: EnvelopeT '[(), Char, String, Int] Identity DoubleEnvelopeT (Identity (SuccEnvelope 3.5))
liftA2EnvT :: (Contains es1 fullEs, Contains es2 fullEs, Applicative m) => (a -> b -> c) -> EnvelopeT es1 m a -> EnvelopeT es2 m b -> EnvelopeT fullEs m c Source #
Combine two EnvelopeTs. Generalize the set of errors to include the errors
from both EnvelopeTs. Similar to liftA2 but more general.
Examples
>>>let env1 = pure "hello" :: EnvelopeT '[Double, Int] Identity String>>>let env2 = pure " world" :: EnvelopeT '[Char] Identity String>>>liftA2EnvT (<>) env1 env2 :: EnvelopeT '[Double, Int, Char] Identity StringEnvelopeT (Identity (SuccEnvelope "hello world"))
If either of the Envelopes is an ErrEnvelope, then return the ErrEnvelope.
>>>let env3 = throwErrEnvT "some err" :: EnvelopeT '[String, Double] Identity Int>>>let env4 = pure 1 :: EnvelopeT '[Char] Identity Int>>>liftA2EnvT (+) env3 env4 :: EnvelopeT '[String, Double, Char] Identity IntEnvelopeT (Identity (ErrEnvelope (Identity "some err")))
>>>let env5 = pure "hello" :: EnvelopeT '[Char] Identity String>>>let env6 = throwErrEnvT 3.5 :: EnvelopeT '[(), Double] Identity String>>>liftA2EnvT (<>) env5 env6 :: EnvelopeT '[Char, (), Double] Identity StringEnvelopeT (Identity (ErrEnvelope (Identity 3.5)))
If both of the EnvelopeTs is an ErrEnvelope, then short-circuit and only
return the first ErrEnvelope.
>>>let env7 = throwErrEnvT 4.5 :: EnvelopeT '[(), Double] Identity String>>>let env8 = throwErrEnvT 'x' :: EnvelopeT '[Int, Char] Identity String>>>liftA2EnvT (<>) env7 env8 :: EnvelopeT '[(), Double, Int, Char] Identity StringEnvelopeT (Identity (ErrEnvelope (Identity 4.5)))
bindEnvT :: (Contains es1 fullEs, Contains es2 fullEs, Monad m) => EnvelopeT es1 m a -> (a -> EnvelopeT es2 m b) -> EnvelopeT fullEs m b Source #
This is like liftA2EnvT but for monadic bind (>>=).
This allows you to bind on EnvelopeTs that contain different errors.
The resulting EnvelopeT must have a superset of the errors in two input
EnvelopeTs.
Examples
>>>let env1 = pure "hello" :: EnvelopeT '[Double, Int] Identity String>>>let f1 str = pure (length str) :: EnvelopeT '[Char] Identity Int>>>bindEnvT env1 f1 :: EnvelopeT '[Double, Int, Char] Identity IntEnvelopeT (Identity (SuccEnvelope 5))
If either of the EnvelopeTs holds an ErrEnvelope, then return the ErrEnvelope.
>>>let env2 = throwErrEnvT "some err" :: EnvelopeT '[String, Double] Identity Int>>>let f2 i = pureSuccEnvT (i + 1) :: EnvelopeT '[Char] Identity Int>>>bindEnvT env2 f2 :: EnvelopeT '[String, Double, Char] Identity IntEnvelopeT (Identity (ErrEnvelope (Identity "some err")))
>>>let env3 = pureSuccEnvT "hello" :: EnvelopeT '[Char] Identity String>>>let f3 _ = throwErrEnvT 3.5 :: EnvelopeT '[(), Double] Identity Int>>>bindEnvT env3 f3 :: EnvelopeT '[Char, (), Double] Identity IntEnvelopeT (Identity (ErrEnvelope (Identity 3.5)))
If both of the Envelopes is an ErrEnvelope, then short-circuit and only
return the first ErrEnvelope.
>>>let env4 = throwErrEnvT 3.5 :: EnvelopeT '[(), Double] Maybe String>>>let f4 _ = throwErrEnvT 'x' :: EnvelopeT '[Int, Char] Maybe String>>>bindEnvT env4 f4 :: EnvelopeT '[Char, (), Double, Int] Maybe StringEnvelopeT (Just (ErrEnvelope (Identity 3.5)))
envTRemove :: forall e es m a. (ElemRemove e es, Functor m) => EnvelopeT es m a -> EnvelopeT (Remove e es) m (Either a e) Source #
This function allows you to try to remove individual error types from an
EnvelopeT.
This can be used to handle only certain error types in an Envelope,
instead of having to handle all of them at the same time. This can be more
convenient than a function like catchesEnvT.
Examples
Pulling out an error in an EnvelopeT:
>>>let env1 = throwErrEnvT "hello" :: EnvelopeT '[String, Double] Identity Float>>>envTRemove env1 :: EnvelopeT '[Double] Identity (Either Float String)EnvelopeT (Identity (SuccEnvelope (Right "hello")))
Failing to pull out an error in an EnvelopeT:
>>>let env2 = throwErrEnvT (3.5 :: Double) :: EnvelopeT '[String, Double] Identity Float>>>envTRemove env2 :: EnvelopeT '[Double] Identity (Either Float String)EnvelopeT (Identity (ErrEnvelope (Identity 3.5)))
Note that if you have an EnvelopeT with multiple errors of the same type,
they will all be handled at the same time:
>>>let env3 = throwErrEnvT (3.5 :: Double) :: EnvelopeT '[String, Double, Char, Double] Identity Float>>>envTRemove env3 :: EnvelopeT '[String, Char] Identity (Either Float Double)EnvelopeT (Identity (SuccEnvelope (Right 3.5)))
SuccEnvelope gets passed through as expected:
>>>let env4 = pureSuccEnvT 3.5 :: EnvelopeT '[String, Double] Identity Float>>>envTRemove env4 :: EnvelopeT '[Double] Identity (Either Float String)EnvelopeT (Identity (SuccEnvelope (Left 3.5)))