{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Language.KURE.Injection
(
Injection(..)
, injectM
, projectM
, projectWithFailMsgM
, injectT
, projectT
, extractT
, promoteT
, projectWithFailMsgT
, promoteWithFailMsgT
, extractR
, promoteR
, extractWithFailMsgR
, promoteWithFailMsgR
) where
import Control.Arrow
#if !MIN_VERSION_base(4,13,0)
import Control.Monad.Fail (MonadFail)
#endif
import Language.KURE.Transform
class Injection a u where
inject :: a -> u
project :: u -> Maybe a
instance Injection a a where
inject :: a -> a
inject :: a -> a
inject = a -> a
forall a. a -> a
id
{-# INLINE inject #-}
project :: a -> Maybe a
project :: a -> Maybe a
project = a -> Maybe a
forall a. a -> Maybe a
Just
{-# INLINE project #-}
instance Injection a (Maybe a) where
inject :: a -> Maybe a
inject :: a -> Maybe a
inject = a -> Maybe a
forall a. a -> Maybe a
Just
{-# INLINE inject #-}
project :: Maybe a -> Maybe a
project :: Maybe a -> Maybe a
project = Maybe a -> Maybe a
forall a. a -> a
id
{-# INLINE project #-}
injectM :: (Monad m, Injection a u) => a -> m u
injectM :: a -> m u
injectM = u -> m u
forall (m :: * -> *) a. Monad m => a -> m a
return (u -> m u) -> (a -> u) -> a -> m u
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> u
forall a u. Injection a u => a -> u
inject
{-# INLINE injectM #-}
projectWithFailMsgM :: (MonadFail m, Injection a u) => String -> u -> m a
projectWithFailMsgM :: String -> u -> m a
projectWithFailMsgM String
msg = m a -> (a -> m a) -> Maybe a -> m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
msg) a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe a -> m a) -> (u -> Maybe a) -> u -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. u -> Maybe a
forall a u. Injection a u => u -> Maybe a
project
{-# INLINE projectWithFailMsgM #-}
projectM :: (MonadFail m, Injection a u) => u -> m a
projectM :: u -> m a
projectM = String -> u -> m a
forall (m :: * -> *) a u.
(MonadFail m, Injection a u) =>
String -> u -> m a
projectWithFailMsgM String
"projectM failed"
{-# INLINE projectM #-}
injectT :: (Monad m, Injection a u) => Transform c m a u
injectT :: Transform c m a u
injectT = (a -> u) -> Transform c m a u
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr a -> u
forall a u. Injection a u => a -> u
inject
{-# INLINE injectT #-}
projectWithFailMsgT :: (MonadFail m, Injection a u) => String -> Transform c m u a
projectWithFailMsgT :: String -> Transform c m u a
projectWithFailMsgT = (u -> m a) -> Transform c m u a
forall k a (m :: k -> *) (b :: k) c.
(a -> m b) -> Transform c m a b
contextfreeT ((u -> m a) -> Transform c m u a)
-> (String -> u -> m a) -> String -> Transform c m u a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> u -> m a
forall (m :: * -> *) a u.
(MonadFail m, Injection a u) =>
String -> u -> m a
projectWithFailMsgM
{-# INLINE projectWithFailMsgT #-}
projectT :: (MonadFail m, Injection a u) => Transform c m u a
projectT :: Transform c m u a
projectT = String -> Transform c m u a
forall (m :: * -> *) a u c.
(MonadFail m, Injection a u) =>
String -> Transform c m u a
projectWithFailMsgT String
"projectT failed"
{-# INLINE projectT #-}
extractT :: (Monad m, Injection a u) => Transform c m u b -> Transform c m a b
Transform c m u b
t = Transform c m a u
forall (m :: * -> *) a u c.
(Monad m, Injection a u) =>
Transform c m a u
injectT Transform c m a u -> Transform c m u b -> Transform c m a b
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Transform c m u b
t
{-# INLINE extractT #-}
promoteWithFailMsgT :: (MonadFail m, Injection a u) => String -> Transform c m a b -> Transform c m u b
promoteWithFailMsgT :: String -> Transform c m a b -> Transform c m u b
promoteWithFailMsgT String
msg Transform c m a b
t = String -> Transform c m u a
forall (m :: * -> *) a u c.
(MonadFail m, Injection a u) =>
String -> Transform c m u a
projectWithFailMsgT String
msg Transform c m u a -> Transform c m a b -> Transform c m u b
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Transform c m a b
t
{-# INLINE promoteWithFailMsgT #-}
promoteT :: (MonadFail m, Injection a u) => Transform c m a b -> Transform c m u b
promoteT :: Transform c m a b -> Transform c m u b
promoteT = String -> Transform c m a b -> Transform c m u b
forall (m :: * -> *) a u c b.
(MonadFail m, Injection a u) =>
String -> Transform c m a b -> Transform c m u b
promoteWithFailMsgT String
"promoteT failed"
{-# INLINE promoteT #-}
extractWithFailMsgR :: (MonadFail m, Injection a u) => String -> Rewrite c m u -> Rewrite c m a
String
msg Rewrite c m u
r = Transform c m a u
forall (m :: * -> *) a u c.
(Monad m, Injection a u) =>
Transform c m a u
injectT Transform c m a u -> Transform c m u a -> Rewrite c m a
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Rewrite c m u
r Rewrite c m u -> Transform c m u a -> Transform c m u a
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> String -> Transform c m u a
forall (m :: * -> *) a u c.
(MonadFail m, Injection a u) =>
String -> Transform c m u a
projectWithFailMsgT String
msg
{-# INLINE extractWithFailMsgR #-}
extractR :: (MonadFail m, Injection a u) => Rewrite c m u -> Rewrite c m a
= String -> Rewrite c m u -> Rewrite c m a
forall (m :: * -> *) a u c.
(MonadFail m, Injection a u) =>
String -> Rewrite c m u -> Rewrite c m a
extractWithFailMsgR String
"extractR failed"
{-# INLINE extractR #-}
promoteWithFailMsgR :: (MonadFail m, Injection a u) => String -> Rewrite c m a -> Rewrite c m u
promoteWithFailMsgR :: String -> Rewrite c m a -> Rewrite c m u
promoteWithFailMsgR String
msg Rewrite c m a
r = String -> Transform c m u a
forall (m :: * -> *) a u c.
(MonadFail m, Injection a u) =>
String -> Transform c m u a
projectWithFailMsgT String
msg Transform c m u a -> Transform c m a u -> Rewrite c m u
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Rewrite c m a
r Rewrite c m a -> Transform c m a u -> Transform c m a u
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Transform c m a u
forall (m :: * -> *) a u c.
(Monad m, Injection a u) =>
Transform c m a u
injectT
{-# INLINE promoteWithFailMsgR #-}
promoteR :: (MonadFail m, Injection a u) => Rewrite c m a -> Rewrite c m u
promoteR :: Rewrite c m a -> Rewrite c m u
promoteR = String -> Rewrite c m a -> Rewrite c m u
forall (m :: * -> *) a u c.
(MonadFail m, Injection a u) =>
String -> Rewrite c m a -> Rewrite c m u
promoteWithFailMsgR String
"promoteR failed"
{-# INLINE promoteR #-}