content: {-# LANGUAGE DataKinds #-}
  {-# LANGUAGE NoImplicitPrelude #-}
  {-# LANGUAGE RankNTypes #-}
  {-# LANGUAGE TypeOperators #-}
  -- |
  -- Module:       Control.Monad.Freer
  -- Description:  Freer - an extensible effects library
  -- Copyright:    (c) 2016 Allele Dev; 2017 Ixperta Solutions s.r.o.
  -- License:      BSD3
  -- Maintainer:   ixcom-core@ixperta.com
  -- Stability:    experimental
  -- Portability:  GHC specific language extensions.
  module Control.Monad.Freer
      (
      -- * Effect Monad
        Eff
  
      -- ** Effect Constraints
      , Member
      , Members
  
      -- ** Sending Arbitrary Effect
      , send
  
      -- ** Lifting Effect Stacks
      , raise
  
      -- * Handling Effects
      , Arr
      , run
      , runM
  
      -- ** Building Effect Handlers
      , runNat
      , runNatS
      , handleRelay
      , handleRelayS
      )
    where
  
  import Control.Applicative (pure)
  import Control.Monad ((>>=))
  import Data.Function (($), (.), const)
  import Data.Tuple (uncurry)
  
  import Control.Monad.Freer.Internal
      ( Arr
      , Eff
      , Member
      , Members
      , handleRelay
      , handleRelayS
      , raise
      , run
      , runM
      , send
      )
  
  
  -- | Variant of 'handleRelay' simplified for the common case.
  runNat
      :: Member m effs
      => (forall a. eff a -> m a)
      -> Eff (eff ': effs) b
      -> Eff effs b
  runNat f = handleRelay pure $ \e -> (send (f e) >>=)
  
  -- | Variant of 'handleRelayS' simplified for the common case.
  runNatS
      :: Member m effs
      => s
      -> (forall a. s -> eff a -> m (s, a))
      -> Eff (eff ': effs) b
      -> Eff effs b
  runNatS s0 f =
      handleRelayS s0 (const pure) $ \s e -> (send (f s e) >>=) . uncurry
  