prob-fx-0.1.0.0: src/Effects/Lift.hs
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{- | For lifting arbitrary monadic computations into an algebraic effect setting
-}
module Effects.Lift (
Lift(..)
, lift
, handleLift) where
import Prog ( call, Member(prj), Prog(..) )
import Data.Function (fix)
-- | Lift effect
newtype Lift m a = Lift (m a)
-- | Lift a monadic computation @m a@ into the effect @Lift m@
lift :: (Member (Lift m) es) => m a -> Prog es a
lift = call . Lift
-- | Handle @Lift m@ as the last effect
handleLift :: forall m w. Monad m => Prog '[Lift m] w -> m w
handleLift (Val x) = return x
handleLift (Op u q) = case prj u of
Just (Lift m) -> m >>= handleLift . q
Nothing -> error "Impossible: Nothing cannot occur"