{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs, DataKinds #-}
{-# LANGUAGE Safe #-}
module Control.Eff.Trace( Trace (..)
, withTrace
, trace
, runTrace
) where
import Control.Eff
import Control.Eff.Extend
import Data.Function (fix)
data Trace v where
Trace :: String -> Trace ()
withTrace :: a -> IO a
withTrace = return
instance Handle Trace r a (IO k) where
handle step q (Trace s) = putStrLn s >> step (q ^$ ())
trace :: Member Trace r => String -> Eff r ()
trace = send . Trace
runTrace :: Eff '[Trace] w -> IO w
runTrace = fix step where
step next = eff return
(\q u -> case u of
U0 x -> handle next q x
_ -> error "Impossible: Nothing to relay!")