Add MonadEffect
This commit is contained in:
parent
0ae1fd7462
commit
8068e02e30
63
src/Effect/Unlift.purs
Normal file
63
src/Effect/Unlift.purs
Normal file
@ -0,0 +1,63 @@
|
||||
module Effect.Unlift where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.Identity.Trans (IdentityT(..))
|
||||
import Control.Monad.Reader (ReaderT(..))
|
||||
import Effect (Effect)
|
||||
import Effect.Class (class MonadEffect)
|
||||
|
||||
-- | Monads which allow their actions to be run in `Effect`.
|
||||
-- |
|
||||
-- | `MonadUnliftEffect` captures the opposite notion of `MonadEffect` - while
|
||||
-- | `MonadEffect` allows an `Effect` to be lifted into another monad,
|
||||
-- | `MonadUnliftEffect` allows a monad other than `Effect` to be run in an
|
||||
-- | `Effect` context.
|
||||
-- |
|
||||
-- | Note that the laws given below require that a monad have no "monadic
|
||||
-- | state", which essentially limits instances to `ReaderT` and `IdentityT`
|
||||
-- | stacks with a base of `Effect`.
|
||||
-- |
|
||||
-- | Instances should satisfy the following laws, which state that
|
||||
-- | `unliftEffect` is a transformer of monads for any given `u` returned by
|
||||
-- | `askUnliftEffect`:
|
||||
-- |
|
||||
-- | ```purescript
|
||||
-- | unliftEffect u <<< pure = pure
|
||||
-- | unliftEffect u (f =<< m) = unliftEffect u <<< f =<< unliftEffect u m
|
||||
-- | ```
|
||||
class MonadEffect m <= MonadUnliftEffect m where
|
||||
-- | Run an `Effect` with access to a runner function that is capable of
|
||||
-- | running a monadic action `m` in `Effect`.
|
||||
withRunInEffect :: forall b. ((m ~> Effect) -> Effect b) -> m b
|
||||
|
||||
instance MonadUnliftEffect Effect where
|
||||
withRunInEffect runAction = runAction identity
|
||||
|
||||
instance MonadUnliftEffect m => MonadUnliftEffect (ReaderT r m) where
|
||||
withRunInEffect runAction = ReaderT \context ->
|
||||
withRunInEffect \runMInEffect ->
|
||||
runAction \(ReaderT reader) ->
|
||||
runMInEffect $ reader context
|
||||
|
||||
instance MonadUnliftEffect m => MonadUnliftEffect (IdentityT m) where
|
||||
withRunInEffect runAction = IdentityT $
|
||||
withRunInEffect \runMInEffect ->
|
||||
runAction \(IdentityT a) ->
|
||||
runMInEffect a
|
||||
|
||||
newtype UnliftEffect m = UnliftEffect (m ~> Effect)
|
||||
|
||||
askUnliftEffect :: forall m. MonadUnliftEffect m => m (UnliftEffect m)
|
||||
askUnliftEffect = withRunInEffect \run -> pure $ UnliftEffect run
|
||||
|
||||
askRunInEffect :: forall m a. MonadUnliftEffect m => m (m a -> Effect a)
|
||||
askRunInEffect = withRunInEffect pure
|
||||
|
||||
withUnliftEffect
|
||||
:: forall m a. MonadUnliftEffect m => (UnliftEffect m -> Effect a) -> m a
|
||||
withUnliftEffect runAction =
|
||||
withRunInEffect \run -> runAction $ UnliftEffect run
|
||||
|
||||
toEffect :: forall m a. MonadUnliftEffect m => m a -> m (Effect a)
|
||||
toEffect m = withRunInEffect \run -> pure $ run m
|
Loading…
Reference in New Issue
Block a user