content: {-# LANGUAGE LinearTypes #-}
  {-# LANGUAGE NoImplicitPrelude #-}
  
  -- |
  -- A thin wrapper on top of "Debug.Trace", providing linear versions of
  -- tracing functions.
  --
  -- It only contains minimal amount of documentation; you should consult
  -- the original "Debug.Trace" module for more detailed information.
  module Debug.Trace.Linear
    ( -- * Tracing
      trace,
      traceShow,
      traceId,
      traceStack,
      traceIO,
      traceM,
      traceShowM,
  
      -- * Eventlog tracing
      traceEvent,
      traceEventIO,
  
      -- * Execution phase markers
      traceMarker,
      traceMarkerIO,
    )
  where
  
  import Data.Functor.Linear
  import Data.Unrestricted.Linear
  import qualified Debug.Trace as NonLinear
  import Prelude.Linear.Internal
  import System.IO.Linear
  import qualified Unsafe.Linear as Unsafe
  import Prelude (Show (..), String)
  
  -- | The 'trace' function outputs the trace message given as its first
  -- argument, before returning the second argument as its result.
  trace :: String %1 -> a %1 -> a
  trace = Unsafe.toLinear2 NonLinear.trace
  
  -- | Like 'trace', but uses 'show' on the argument to convert it to
  -- a 'String'.
  traceShow :: (Show a) => a -> b %1 -> b
  traceShow a = Unsafe.toLinear (NonLinear.traceShow a)
  
  -- | Like 'trace' but returns the message instead of a third value.
  traceId :: String %1 -> String
  traceId s = dup s & \(s', s'') -> trace s' s''
  
  -- | Like 'trace', but additionally prints a call stack if one is
  -- available.
  traceStack :: String %1 -> a %1 -> a
  traceStack = Unsafe.toLinear2 NonLinear.traceStack
  
  -- | The 'traceIO' function outputs the trace message from the IO monad.
  -- This sequences the output with respect to other IO actions.
  traceIO :: String %1 -> IO ()
  traceIO s = fromSystemIO (Unsafe.toLinear NonLinear.traceIO s)
  
  -- | Like 'trace' but returning unit in an arbitrary 'Applicative'
  -- context. Allows for convenient use in do-notation.
  traceM :: (Applicative f) => String %1 -> f ()
  traceM s = trace s $ pure ()
  
  -- | Like 'traceM', but uses 'show' on the argument to convert it to a
  -- 'String'.
  traceShowM :: (Show a, Applicative f) => a -> f ()
  traceShowM a = traceM (show a)
  
  -- | The 'traceEvent' function behaves like 'trace' with the difference
  -- that the message is emitted to the eventlog, if eventlog profiling is
  -- available and enabled at runtime.
  traceEvent :: String %1 -> a %1 -> a
  traceEvent = Unsafe.toLinear2 NonLinear.traceEvent
  
  -- | The 'traceEventIO' function emits a message to the eventlog, if
  -- eventlog profiling is available and enabled at runtime.
  traceEventIO :: String %1 -> IO ()
  traceEventIO s = fromSystemIO (Unsafe.toLinear NonLinear.traceEventIO s)
  
  -- | The 'traceMarker' function emits a marker to the eventlog, if eventlog
  -- profiling is available and enabled at runtime. The @String@ is the name
  -- of the marker. The name is just used in the profiling tools to help you
  -- keep clear which marker is which.
  traceMarker :: String %1 -> a %1 -> a
  traceMarker = Unsafe.toLinear2 NonLinear.traceMarker
  
  -- | The 'traceMarkerIO' function emits a marker to the eventlog, if
  -- eventlog profiling is available and enabled at runtime.
  traceMarkerIO :: String %1 -> IO ()
  traceMarkerIO s = fromSystemIO (Unsafe.toLinear NonLinear.traceMarkerIO s)
  