{-# LANGUAGE TemplateHaskell #-}
module Polysemy.Trace
  ( 
    Trace (..)
    
  , trace
    
  , traceToIO
  , runTraceList
  , ignoreTrace
  , traceToOutput
    
  , outputToTrace
  ) where
import Polysemy
import Polysemy.Output
data Trace m a where
  Trace :: String -> Trace m ()
makeSem ''Trace
traceToIO :: Member (Embed IO) r => Sem (Trace ': r) a -> Sem r a
traceToIO = interpret $ \case
  Trace m -> embed $ putStrLn m
{-# INLINE traceToIO #-}
ignoreTrace :: Sem (Trace ': r) a -> Sem r a
ignoreTrace = interpret $ \case
  Trace _ -> pure ()
{-# INLINE ignoreTrace #-}
traceToOutput
    :: Member (Output String) r
    => Sem (Trace ': r) a
    -> Sem r a
traceToOutput = interpret $ \case
  Trace m -> output m
{-# INLINE traceToOutput #-}
runTraceList
    :: Sem (Trace ': r) a
    -> Sem r ([String], a)
runTraceList = runOutputList . reinterpret (
  \case
    Trace m -> output m
  )
{-# INLINE runTraceList #-}
outputToTrace
    :: ( Show w
       , Member Trace r
       )
    => Sem (Output w ': r) a
    -> Sem r a
outputToTrace = interpret $ \case
  Output m -> trace $ show m
{-# INLINE outputToTrace #-}