    -- | A simple system so that the Cryptol driver can communicate
    -- with users (or not).
    module Cryptol.Utils.Logger
      ( Logger

      , stdoutLogger
      , stderrLogger
      , handleLogger
      , quietLogger
      , funLogger

      , logPutStr
      , logPutStrLn
      , logPrint
      ) where

    import System.IO(Handle, hPutStr, stdout, stderr)
    import Control.DeepSeq(NFData(..))

    -- | A logger provides simple abstraction for sending messages.
    newtype Logger = Logger (String -> IO ())

    instance NFData Logger where
      rnf :: Logger -> ()
    rnf (Logger String -> IO ()
    x) = (String -> IO ()) -> ()
    forall a. NFData a => a -> ()
    rnf String -> IO ()
    x

    -- | Send the given string to the log.
    logPutStr :: Logger -> String -> IO ()
    logPutStr :: Logger -> String -> IO ()
    logPutStr (Logger String -> IO ()
    f) = String -> IO ()
    f

    -- | Send the given string with a newline at the end.
    logPutStrLn :: Logger -> String -> IO ()
    logPutStrLn :: Logger -> String -> IO ()
    logPutStrLn Logger
    l String
    s = Logger -> String -> IO ()
    logPutStr Logger
    l (String
    s String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "\n")

    -- | Send the given value using its 'Show' instance.
    -- Adds a newline at the end.
    logPrint :: Show a => Logger -> a -> IO ()
    logPrint :: forall a. Show a => Logger -> a -> IO ()
    logPrint Logger
    l a
    a = Logger -> String -> IO ()
    logPutStrLn Logger
    l (a -> String
    forall a. Show a => a -> String
    show a
    a)

    -- | A logger that ignores all messages.
    quietLogger :: Logger
    quietLogger :: Logger
    quietLogger = (String -> IO ()) -> Logger
    Logger (IO () -> String -> IO ()
    forall a b. a -> b -> a
    const (() -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()))

    -- | Log to the given handle.
    handleLogger :: Handle -> Logger
    handleLogger :: Handle -> Logger
    handleLogger Handle
    h = (String -> IO ()) -> Logger
    Logger (Handle -> String -> IO ()
    hPutStr Handle
    h)

    -- | Log to stdout.
    stdoutLogger :: Logger
    stdoutLogger :: Logger
    stdoutLogger = Handle -> Logger
    handleLogger Handle
    stdout

    -- | Log to stderr.
    stderrLogger :: Logger
    stderrLogger :: Logger
    stderrLogger = Handle -> Logger
    handleLogger Handle
    stderr

    -- | Just use this function for logging.
    funLogger :: (String -> IO ()) -> Logger
    funLogger :: (String -> IO ()) -> Logger
    funLogger = (String -> IO ()) -> Logger
    Logger