{-# LANGUAGE TemplateHaskell #-}
module Polysemy.Fixpoint
  ( 
    Fixpoint (..)
    
  , module Polysemy.Fixpoint
  ) where
import Control.Monad.Fix
import Polysemy
import Polysemy.Internal.Fixpoint
runFixpoint
    :: (∀ x. Sem r x -> x)
    -> Sem (Fixpoint ': r) a
    -> Sem r a
runFixpoint lower = interpretH $ \case
  Fixpoint mf -> do
    c <- bindT mf
    pure $ fix $ lower . runFixpoint lower . c
runFixpointM
    :: ( MonadFix m
       , Member (Embed m) r
       )
    => (∀ x. Sem r x -> m x)
    -> Sem (Fixpoint ': r) a
    -> Sem r a
runFixpointM lower = interpretH $ \case
  Fixpoint mf -> do
    c <- bindT mf
    embed $ mfix $ lower . runFixpointM lower . c