module Embedding ( Embedding (..) , embed , extract , extractIgnoringError , dimapEmbedding ) where import Internal.Prelude -- | Targets a value that is optionally present in some stateful monadic context data Embedding (con :: (Type -> Type) -> Constraint) e a = Embedding { embed :: forall m. con m => Maybe a -> m () -- ^ Sets or clears the value , extract :: forall m. (Functor m, con m) => m (Either e (Maybe a)) -- ^ Removes the value if present, returning what was removed } embed :: con m => Embedding con e a -> Maybe a -> m () embed Embedding {embed = x} = x extract :: (Functor m, con m) => Embedding con e a -> m (Either e (Maybe a)) extract Embedding {extract = x} = x extractIgnoringError :: (Functor m, con m) => Embedding con e a -> m (Maybe a) extractIgnoringError e = extract e <&> fromRight Nothing dimapEmbedding :: (a -> Either e b) -> (b -> a) -> Embedding con e a -> Embedding con e b dimapEmbedding g f Embedding {embed = embed', extract = extract'} = Embedding { embed = embed' . fmap f , extract = extract' <&> \case Left e -> Left e Right Nothing -> Right Nothing Right (Just x) -> Just <$> g x }