rio-0.1.22.0: A standard library for Haskell

Safe Haskell | None
Language | Haskell2010

RIO

Contents

- Custom `Prelude`
- The `RIO` Monad
  - `SimpleApp`
- `MonadIO` and `MonadUnliftIO`
- Logger
- Display
- Optics
- Concurrency
  - Async
  - STM
  - Chan
  - Timeout
- Exceptions
- Files and handles
- Exit
- Mutable Variables
  - SomeRef
  - URef
  - IORef
  - MVar
  - QSem
  - QSemN
  - Memoize
  - Deque
- Debugging

Synopsis

- module RIO.Prelude
- module RIO.Prelude.Types
- newtype RIO env a = RIO {
  - unRIO :: ReaderT env IO a
  }
- liftRIO :: (MonadIO m, MonadReader env m) => RIO env a -> m a
- runRIO :: MonadIO m => env -> RIO env a -> m a
- module RIO.Prelude.Simple
- module Control.Monad.IO.Unlift
- data CallStack
- withLogFunc :: MonadUnliftIO m => LogOptions -> (LogFunc -> m a) -> m a
- newLogFunc :: (MonadIO n, MonadIO m) => LogOptions -> n (LogFunc, m ())
- data LogFunc
- class HasLogFunc env where
  - logFuncL :: Lens' env LogFunc
- logOptionsHandle :: MonadIO m => Handle -> Bool -> m LogOptions
- data LogOptions
- setLogMinLevel :: LogLevel -> LogOptions -> LogOptions
- setLogMinLevelIO :: IO LogLevel -> LogOptions -> LogOptions
- setLogVerboseFormat :: Bool -> LogOptions -> LogOptions
- setLogVerboseFormatIO :: IO Bool -> LogOptions -> LogOptions
- setLogTerminal :: Bool -> LogOptions -> LogOptions
- setLogUseTime :: Bool -> LogOptions -> LogOptions
- setLogUseColor :: Bool -> LogOptions -> LogOptions
- setLogUseLoc :: Bool -> LogOptions -> LogOptions
- setLogFormat :: (Utf8Builder -> Utf8Builder) -> LogOptions -> LogOptions
- setLogLevelColors :: (LogLevel -> Utf8Builder) -> LogOptions -> LogOptions
- setLogSecondaryColor :: Utf8Builder -> LogOptions -> LogOptions
- setLogAccentColors :: (Int -> Utf8Builder) -> LogOptions -> LogOptions
- logDebug :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => Utf8Builder -> m ()
- logInfo :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => Utf8Builder -> m ()
- logWarn :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => Utf8Builder -> m ()
- logError :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => Utf8Builder -> m ()
- logOther :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => Text -> Utf8Builder -> m ()
- logSticky :: (MonadIO m, HasCallStack, MonadReader env m, HasLogFunc env) => Utf8Builder -> m ()
- logStickyDone :: (MonadIO m, HasCallStack, MonadReader env m, HasLogFunc env) => Utf8Builder -> m ()
- logDebugS :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => LogSource -> Utf8Builder -> m ()
- logInfoS :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => LogSource -> Utf8Builder -> m ()
- logWarnS :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => LogSource -> Utf8Builder -> m ()
- logErrorS :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => LogSource -> Utf8Builder -> m ()
- logOtherS :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => Text -> LogSource -> Utf8Builder -> m ()
- logGeneric :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => LogSource -> LogLevel -> Utf8Builder -> m ()
- mkLogFunc :: (CallStack -> LogSource -> LogLevel -> Utf8Builder -> IO ()) -> LogFunc
- logOptionsMemory :: MonadIO m => m (IORef Builder, LogOptions)
- data LogLevel
  - = LevelDebug
  - | LevelInfo
  - | LevelWarn
  - | LevelError
  - | LevelOther !Text
- type LogSource = Text
- displayCallStack :: CallStack -> Utf8Builder
- noLogging :: (HasLogFunc env, MonadReader env m) => m a -> m a
- logFuncUseColorL :: HasLogFunc env => SimpleGetter env Bool
- logFuncLogLevelColorsL :: HasLogFunc env => SimpleGetter env (LogLevel -> Utf8Builder)
- logFuncSecondaryColorL :: HasLogFunc env => SimpleGetter env Utf8Builder
- logFuncAccentColorsL :: HasLogFunc env => SimpleGetter env (Int -> Utf8Builder)
- glog :: (MonadIO m, HasCallStack, HasGLogFunc env, MonadReader env m) => GMsg env -> m ()
- data GLogFunc msg
- gLogFuncClassic :: (HasLogLevel msg, HasLogSource msg, Display msg) => LogFunc -> GLogFunc msg
- mkGLogFunc :: (CallStack -> msg -> IO ()) -> GLogFunc msg
- contramapMaybeGLogFunc :: (a -> Maybe b) -> GLogFunc b -> GLogFunc a
- contramapGLogFunc :: (a -> b) -> GLogFunc b -> GLogFunc a
- class HasGLogFunc env where
  - type GMsg env
  - gLogFuncL :: Lens' env (GLogFunc (GMsg env))
- class HasLogLevel msg where
  - getLogLevel :: msg -> LogLevel
- class HasLogSource msg where
  - getLogSource :: msg -> LogSource
- type family GMsg env
- class Display a where
  - display :: a -> Utf8Builder
  - textDisplay :: a -> Text
- newtype Utf8Builder = Utf8Builder {
  - getUtf8Builder :: Builder
  }
- displayShow :: Show a => a -> Utf8Builder
- utf8BuilderToText :: Utf8Builder -> Text
- utf8BuilderToLazyText :: Utf8Builder -> Text
- displayBytesUtf8 :: ByteString -> Utf8Builder
- writeFileUtf8Builder :: MonadIO m => FilePath -> Utf8Builder -> m ()
- to :: (s -> a) -> SimpleGetter s a
- (^.) :: s -> Getting a s a -> a
- (^..) :: s -> Getting (Endo [a]) s a -> [a]
- (^?) :: s -> Getting (First a) s a -> Maybe a
- view :: MonadReader s m => Getting a s a -> m a
- (.~) :: ASetter s t a b -> b -> s -> t
- preview :: MonadReader s m => Getting (First a) s a -> m (Maybe a)
- type Lens' s a = Lens s s a a
- type Lens s t a b = forall (f :: Type -> Type). Functor f => (a -> f b) -> s -> f t
- type Getting r s a = (a -> Const r a) -> s -> Const r s
- type SimpleGetter s a = forall r. Getting r s a
- type ASetter' s a = ASetter s s a a
- type ASetter s t a b = (a -> Identity b) -> s -> Identity t
- sets :: ((a -> b) -> s -> t) -> ASetter s t a b
- (%~) :: ASetter s t a b -> (a -> b) -> s -> t
- over :: ASetter s t a b -> (a -> b) -> s -> t
- set :: ASetter s t a b -> b -> s -> t
- lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b
- data ThreadId
- myThreadId :: MonadIO m => m ThreadId
- isCurrentThreadBound :: MonadIO m => m Bool
- threadWaitRead :: MonadIO m => Fd -> m ()
- threadWaitWrite :: MonadIO m => Fd -> m ()
- threadDelay :: MonadIO m => Int -> m ()
- yieldThread :: MonadIO m => m ()
- module UnliftIO.Async
- module UnliftIO.STM
- module UnliftIO.Chan
- module UnliftIO.Timeout
- module UnliftIO.Exception
- throwM :: (MonadThrow m, HasCallStack, Exception e) => e -> m a
- module UnliftIO.IO
- module UnliftIO.Temporary
- hPutBuilder :: MonadIO m => Handle -> Builder -> m ()
- withLazyFile :: MonadUnliftIO m => FilePath -> (ByteString -> m a) -> m a
- withLazyFileUtf8 :: MonadUnliftIO m => FilePath -> (Text -> m a) -> m a
- readFileBinary :: MonadIO m => FilePath -> m ByteString
- writeFileBinary :: MonadIO m => FilePath -> ByteString -> m ()
- readFileUtf8 :: MonadIO m => FilePath -> m Text
- writeFileUtf8 :: MonadIO m => FilePath -> Text -> m ()
- data ExitCode
  - = ExitSuccess
  - | ExitFailure Int
- exitWith :: MonadIO m => ExitCode -> m a
- exitFailure :: MonadIO m => m a
- exitSuccess :: MonadIO m => m a
- data SomeRef a
- mapRIO :: (outer -> inner) -> RIO inner a -> RIO outer a
- class HasStateRef s env | env -> s where
  - stateRefL :: Lens' env (SomeRef s)
- class HasWriteRef w env | env -> w where
  - writeRefL :: Lens' env (SomeRef w)
- newSomeRef :: MonadIO m => a -> m (SomeRef a)
- newUnboxedSomeRef :: (MonadIO m, Unbox a) => a -> m (SomeRef a)
- readSomeRef :: MonadIO m => SomeRef a -> m a
- writeSomeRef :: MonadIO m => SomeRef a -> a -> m ()
- modifySomeRef :: MonadIO m => SomeRef a -> (a -> a) -> m ()
- data URef s a
- type IOURef = URef (PrimState IO)
- newURef :: (PrimMonad m, Unbox a) => a -> m (URef (PrimState m) a)
- readURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> m a
- writeURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> a -> m ()
- modifyURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> (a -> a) -> m ()
- module UnliftIO.IORef
- module UnliftIO.MVar
- module UnliftIO.QSem
- module UnliftIO.QSemN
- module UnliftIO.Memoize
- module RIO.Deque
- trace :: Text -> a -> a
- traceIO :: MonadIO m => Text -> m ()
- traceMarkerIO :: MonadIO m => Text -> m ()
- traceMarker :: Text -> a -> a
- traceEventIO :: MonadIO m => Text -> m ()
- traceEvent :: Text -> a -> a
- traceStack :: Text -> a -> a
- traceShowM :: (Show a, Applicative f) => a -> f ()
- traceM :: Applicative f => Text -> f ()
- traceShowId :: Show a => a -> a
- traceShow :: Show a => a -> b -> b
- traceId :: Text -> Text
- traceShowIO :: (Show a, MonadIO m) => a -> m ()
- traceShowEvent :: Show a => a -> b -> b
- traceShowEventIO :: (Show a, MonadIO m) => a -> m ()
- traceShowMarker :: Show a => a -> b -> b
- traceShowMarkerIO :: (Show a, MonadIO m) => a -> m ()
- traceShowStack :: Show a => a -> b -> b
- traceDisplay :: Display a => a -> b -> b
- traceDisplayId :: Display a => a -> a
- traceDisplayIO :: (Display a, MonadIO m) => a -> m ()
- traceDisplayM :: (Display a, Applicative f) => a -> f ()
- traceDisplayEvent :: Display a => a -> b -> b
- traceDisplayEventIO :: (Display a, MonadIO m) => a -> m ()
- traceDisplayMarker :: Display a => a -> b -> b
- traceDisplayMarkerIO :: (Display a, MonadIO m) => a -> m ()
- traceDisplayStack :: Display a => a -> b -> b

# Custom `Prelude`

One of the core features of `rio` is that it can be used as a `Prelude` replacement. Therefore it is best to disable the default `Prelude` with: NoImplicitPrelude pragma:

    {-# LANGUAGE NoImplicitPrelude #-}
    import RIO

Some functions not exported here can be found in RIO.Partial: `fromJust`, `read`, `toEnum`, `pred`, `succ`.

module RIO.Prelude

module RIO.Prelude.Types

# The `RIO` Monad

newtype RIO env a #

The Reader+IO monad. This is different from a `ReaderT` because:

- It's not a transformer, it hardcodes IO for simpler usage and error messages.
- Instances of typeclasses like `MonadLogger` are implemented using classes defined on the environment, instead of using an underlying monad.

Constructors

RIO |

Fields

- unRIO :: ReaderT env IO a

#### Instances

Instances details

MonadReader env (RIO env) # |
Instance details Defined in RIO.Prelude.RIO Methods ask :: RIO env env # local :: (env -> env) -> RIO env a -> RIO env a # reader :: (env -> a) -> RIO env a #
HasStateRef s env => MonadState s (RIO env) # |
Instance details Defined in RIO.Prelude.RIO Methods get :: RIO env s # put :: s -> RIO env () # state :: (s -> (a, s)) -> RIO env a #
(Monoid w, HasWriteRef w env) => MonadWriter w (RIO env) # |
Instance details Defined in RIO.Prelude.RIO Methods writer :: (a, w) -> RIO env a # tell :: w -> RIO env () # listen :: RIO env a -> RIO env (a, w) # pass :: RIO env (a, w -> w) -> RIO env a #
MonadIO (RIO env) # |
Instance details Defined in RIO.Prelude.RIO Methods liftIO :: IO a -> RIO env a #
MonadThrow (RIO env) # |
Instance details Defined in RIO.Prelude.RIO Methods throwM :: (HasCallStack, Exception e) => e -> RIO env a #
Applicative (RIO env) # |
Instance details Defined in RIO.Prelude.RIO Methods pure :: a -> RIO env a # (<*>) :: RIO env (a -> b) -> RIO env a -> RIO env b # liftA2 :: (a -> b -> c) -> RIO env a -> RIO env b -> RIO env c # (*>) :: RIO env a -> RIO env b -> RIO env b # (<*) :: RIO env a -> RIO env b -> RIO env a #
Functor (RIO env) # |
Instance details Defined in RIO.Prelude.RIO Methods fmap :: (a -> b) -> RIO env a -> RIO env b # (<$) :: a -> RIO env b -> RIO env a #
Monad (RIO env) # |
Instance details Defined in RIO.Prelude.RIO Methods (>>=) :: RIO env a -> (a -> RIO env b) -> RIO env b # (>>) :: RIO env a -> RIO env b -> RIO env b # return :: a -> RIO env a #
PrimMonad (RIO env) # |

Instance details

Defined in RIO.Prelude.RIO

Associated Types

type PrimState (RIO env) |
Instance details Defined in RIO.Prelude.RIO type PrimState (RIO env) = PrimState IO

Methods

primitive :: (State# (PrimState (RIO env)) -> (# State# (PrimState (RIO env)), a #)) -> RIO env a #

MonadUnliftIO (RIO env) # |
Instance details Defined in RIO.Prelude.RIO Methods withRunInIO :: ((forall a. RIO env a -> IO a) -> IO b) -> RIO env b #
Monoid a => Monoid (RIO env a) # |
Instance details Defined in RIO.Prelude.RIO Methods mempty :: RIO env a # mappend :: RIO env a -> RIO env a -> RIO env a # mconcat :: [RIO env a] -> RIO env a #
Semigroup a => Semigroup (RIO env a) # |
Instance details Defined in RIO.Prelude.RIO Methods (<>) :: RIO env a -> RIO env a -> RIO env a # sconcat :: NonEmpty (RIO env a) -> RIO env a # stimes :: Integral b => b -> RIO env a -> RIO env a #
type PrimState (RIO env) # |
Instance details Defined in RIO.Prelude.RIO type PrimState (RIO env) = PrimState IO

liftRIO :: (MonadIO m, MonadReader env m) => RIO env a -> m a #

Abstract `RIO` to an arbitrary `MonadReader` instance, which can handle IO.

Since: 0.0.1.0

runRIO :: MonadIO m => env -> RIO env a -> m a #

Using the environment run in IO the action that requires that environment.

Since: 0.0.1.0

## `SimpleApp`

If all you need is just some default environment that does basic logging and allows spawning processes, then you can use `SimpleApp`:

    {-# LANGUAGE OverloadedStrings #-}
    module Main where

    main :: IO ()
    main =
      runSimpleApp $ do
        logInfo "Hello World!"

Note the OverloadedStrings extension, which is enabled to simplify logging.

module RIO.Prelude.Simple

# `MonadIO` and `MonadUnliftIO`

module Control.Monad.IO.Unlift

# Logger

The logging system in RIO is built upon "log functions", which are accessed in RIO's environment via a class like "has log function". There are two provided:

- In the common case: for logging plain text (via `Utf8Builder`) efficiently, there is `LogFunc`, which can be created via `withLogFunc`, and is accessed via `HasLogFunc`. This provides all the classical logging facilities: timestamped text output with log levels and colors (if terminal-supported) to the terminal. We log output via `logInfo`, `logDebug`, etc.
- In the advanced case: where logging takes on a more semantic meaning and the logs need to be digested, acted upon, translated or serialized upstream (to e.g. a JSON logging server), we have `GLogFunc` (as in "generic log function"), and is accessed via `HasGLogFunc`. In this case, we log output via `glog`. See the Type-generic logger section for more information.

data CallStack #

`CallStack`s are a lightweight method of obtaining a partial call-stack at any point in the program.

A function can request its call-site with the `HasCallStack` constraint. For example, we can define

    putStrLnWithCallStack :: HasCallStack => String -> IO ()

as a variant of `putStrLn` that will get its call-site and print it, along with the string given as argument. We can access the call-stack inside `putStrLnWithCallStack` with `callStack`.

    >>> :{
    putStrLnWithCallStack :: HasCallStack => String -> IO ()
    putStrLnWithCallStack msg = do
      putStrLn msg
      putStrLn (prettyCallStack callStack)
    :}

Thus, if we call `putStrLnWithCallStack` we will get a formatted call-stack alongside our string.

    >>> putStrLnWithCallStack "hello"
    hello
    CallStack (from HasCallStack):
      putStrLnWithCallStack, called at <interactive>:... in interactive:Ghci...

GHC solves `HasCallStack` constraints in three steps:

1. If there is a `CallStack` in scope -- i.e. the enclosing function has a `HasCallStack` constraint -- GHC will append the new call-site to the existing `CallStack`.
2. If there is no `CallStack` in scope -- e.g. in the GHCi session above -- and the enclosing definition does not have an explicit type signature, GHC will infer a `HasCallStack` constraint for the enclosing definition (subject to the monomorphism restriction).
3. If there is no `CallStack` in scope and the enclosing definition has an explicit type signature, GHC will solve the `HasCallStack` constraint for the singleton `CallStack` containing just the current call-site.

`CallStack`s do not interact with the RTS and do not require compilation with `-prof`. On the other hand, as they are built up explicitly via the `HasCallStack` constraints, they will generally not contain as much information as the simulated call-stacks maintained by the RTS.

A `CallStack` is a `[(String, SrcLoc)]`. The `String` is the name of function that was called, the `SrcLoc` is the call-site. The list is ordered with the most recently called function at the head.

NOTE: The intrepid user may notice that `HasCallStack` is just an alias for an implicit parameter `?callStack :: CallStack`. This is an implementation detail and should not be considered part of the `CallStack` API, we may decide to change the implementation in the future.

@since base-4.8.1.0

#### Instances

Instances details

NFData CallStack | Since: deepseq-1.4.2.0
Instance details Defined in Control.DeepSeq Methods rnf :: CallStack -> () #
IsList CallStack | Be aware that 'fromList . toList = id' only for unfrozen `CallStack`s, since `toList` removes frozenness information. @since base-4.9.0.0

Instance details

Defined in GHC.Internal.IsList

Associated Types

type Item CallStack |
Instance details Defined in GHC.Internal.IsList type Item CallStack = (String, SrcLoc)

Methods

fromList :: [Item CallStack] -> CallStack #

fromListN :: Int -> [Item CallStack] -> CallStack #

toList :: CallStack -> [Item CallStack] #

Show CallStack | @since base-4.9.0.0
Instance details Defined in GHC.Internal.Show Methods showsPrec :: Int -> CallStack -> ShowS # show :: CallStack -> String # showList :: [CallStack] -> ShowS #
type Item CallStack |
Instance details Defined in GHC.Internal.IsList type Item CallStack = (String, SrcLoc)

withLogFunc :: MonadUnliftIO m => LogOptions -> (LogFunc -> m a) -> m a #

Given a `LogOptions` value, run the given function with the specified `LogFunc`. A common way to use this function is:

    let isVerbose = False -- get from the command line instead
    logOptions' <- logOptionsHandle stderr isVerbose
    let logOptions = setLogUseTime True logOptions'
    withLogFunc logOptions $ \lf -> do
      let app = App -- application specific environment
            { appLogFunc = lf
            , appOtherStuff = ...
            }
      runRIO app $ do
        logInfo "Starting app"
        myApp

Since: 0.0.0.0

newLogFunc :: (MonadIO n, MonadIO m) => LogOptions -> n (LogFunc, m ()) #

Given a `LogOptions` value, returns both a new `LogFunc` and a sub-routine that disposes it.

Intended for use if you want to deal with the teardown of `LogFunc` yourself, otherwise prefer the `withLogFunc` function instead.

Since: 0.1.3.0

data LogFunc #

A logging function, wrapped in a newtype for better error messages.

An implementation may choose any behavior of this value it wishes, including printing to standard output or no action at all.

Since: 0.0.0.0

#### Instances

Instances details

Monoid LogFunc # | `mempty` peforms no logging. Since: 0.0.0.0
Instance details Defined in RIO.Prelude.Logger Methods mempty :: LogFunc # mappend :: LogFunc -> LogFunc -> LogFunc # mconcat :: [LogFunc] -> LogFunc #
Semigroup LogFunc # | Perform both sets of actions per log entry. Since: 0.0.0.0
Instance details Defined in RIO.Prelude.Logger Methods (<>) :: LogFunc -> LogFunc -> LogFunc # sconcat :: NonEmpty LogFunc -> LogFunc # stimes :: Integral b => b -> LogFunc -> LogFunc #
HasLogFunc LogFunc # |
Instance details Defined in RIO.Prelude.Logger Methods logFuncL :: Lens' LogFunc LogFunc #

class HasLogFunc env where #

Environment values with a logging function.

Since: 0.0.0.0

Methods

logFuncL :: Lens' env LogFunc #

#### Instances

Instances details

HasLogFunc LogFunc # |
Instance details Defined in RIO.Prelude.Logger Methods logFuncL :: Lens' LogFunc LogFunc #
HasLogFunc SimpleApp # |
Instance details Defined in RIO.Prelude.Simple Methods logFuncL :: Lens' SimpleApp LogFunc #
HasLogFunc LoggedProcessContext # |
Instance details Defined in RIO.Process Methods logFuncL :: Lens' LoggedProcessContext LogFunc #

logOptionsHandle #

Arguments

:: MonadIO m |
=> Handle |
-> Bool | Verbose Flag
-> m LogOptions |

Create a `LogOptions` value from the given `Handle` and whether to perform verbose logging or not. Individiual settings can be overridden using appropriate `set` functions. Logging output is guaranteed to be non-interleaved only for a UTF-8 `Handle` in a multi-thread environment.

When Verbose Flag is `True`, the following happens:

- `setLogVerboseFormat` is called with `True`
- `setLogUseColor` is called with `True` (except on Windows)
- `setLogUseLoc` is called with `True`
- `setLogUseTime` is called with `True`
- `setLogMinLevel` is called with `Debug` log level

Since: 0.0.0.0

data LogOptions #

Configuration for how to create a `LogFunc`. Intended to be used with the `withLogFunc` function.

Since: 0.0.0.0

setLogMinLevel :: LogLevel -> LogOptions -> LogOptions #

Set the minimum log level. Messages below this level will not be printed.

Default: in verbose mode, `LevelDebug`. Otherwise, `LevelInfo`.

Since: 0.0.0.0

setLogMinLevelIO :: IO LogLevel -> LogOptions -> LogOptions #

Refer to `setLogMinLevel`. This modifier allows to alter the verbose format value dynamically at runtime.

Default: in verbose mode, `LevelDebug`. Otherwise, `LevelInfo`.

Since: 0.1.3.0

setLogVerboseFormat :: Bool -> LogOptions -> LogOptions #

Use the verbose format for printing log messages.

Default: follows the value of the verbose flag.

Since: 0.0.0.0

setLogVerboseFormatIO :: IO Bool -> LogOptions -> LogOptions #

Refer to `setLogVerboseFormat`. This modifier allows to alter the verbose format value dynamically at runtime.

Default: follows the value of the verbose flag.

Since: 0.1.3.0

setLogTerminal :: Bool -> LogOptions -> LogOptions #

Do we treat output as a terminal. If `True`, we will enable sticky logging functionality.

Default: checks if the `Handle` provided to `logOptionsHandle` is a terminal with `hIsTerminalDevice`.

Since: 0.0.0.0

setLogUseTime :: Bool -> LogOptions -> LogOptions #

Include the time when printing log messages.

Default: `True` in debug mode, `False` otherwise.

Since: 0.0.0.0

setLogUseColor :: Bool -> LogOptions -> LogOptions #

Use ANSI color codes in the log output.

Default: `True` if in verbose mode and the `Handle` is a terminal device.

Since: 0.0.0.0

setLogUseLoc :: Bool -> LogOptions -> LogOptions #

Use code location in the log output.

Default: `True` if in verbose mode, `False` otherwise.

Since: 0.1.2.0

setLogFormat :: (Utf8Builder -> Utf8Builder) -> LogOptions -> LogOptions #

Set format method for messages

Default: `id`

Since: 0.1.13.0

setLogLevelColors :: (LogLevel -> Utf8Builder) -> LogOptions -> LogOptions #

ANSI color codes for `LogLevel` in the log output.

Default: `LevelDebug` = "\ESC[32m" -- Green `LevelInfo` = "\ESC[34m" -- Blue `LevelWarn` = "\ESC[33m" -- Yellow `LevelError` = "\ESC[31m" -- Red `LevelOther` _ = "\ESC[35m" -- Magenta

Since: 0.1.18.0

setLogSecondaryColor :: Utf8Builder -> LogOptions -> LogOptions #

ANSI color codes for secondary content in the log output.

Default: "\ESC[90m" -- Bright black (gray)

Since: 0.1.18.0

setLogAccentColors #

Arguments

:: (Int -> Utf8Builder) | This should be a total function.
-> LogOptions |
-> LogOptions |

ANSI color codes for accents in the log output. Accent colors are indexed by `Int`.

Default: `const` "\ESC[92m" -- Bright green, for all indicies

Since: 0.1.18.0

logDebug :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => Utf8Builder -> m () #

Log a debug level message with no source.

Since: 0.0.0.0

logInfo :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => Utf8Builder -> m () #

Log an info level message with no source.

Since: 0.0.0.0

logWarn :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => Utf8Builder -> m () #

Log a warn level message with no source.

Since: 0.0.0.0

logError :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => Utf8Builder -> m () #

Log an error level message with no source.

Since: 0.0.0.0

logOther #

Arguments

:: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) |
=> Text | level
-> Utf8Builder |
-> m () |

Log a message with the specified textual level and no source.

Since: 0.0.0.0

logSticky :: (MonadIO m, HasCallStack, MonadReader env m, HasLogFunc env) => Utf8Builder -> m () #

Write a "sticky" line to the terminal. Any subsequent lines will overwrite this one, and that same line will be repeated below again. In other words, the line sticks at the bottom of the output forever. Running this function again will replace the sticky line with a new sticky line. When you want to get rid of the sticky line, run `logStickyDone`.

Note that not all `LogFunc` implementations will support sticky messages as described. However, the `withLogFunc` implementation provided by this module does.

Since: 0.0.0.0

logStickyDone :: (MonadIO m, HasCallStack, MonadReader env m, HasLogFunc env) => Utf8Builder -> m () #

This will print out the given message with a newline and disable any further stickiness of the line until a new call to `logSticky` happens.

Since: 0.0.0.0

logDebugS :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => LogSource -> Utf8Builder -> m () #

Log a debug level message with the given source.

Since: 0.0.0.0

logInfoS :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => LogSource -> Utf8Builder -> m () #

Log an info level message with the given source.

Since: 0.0.0.0

logWarnS :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => LogSource -> Utf8Builder -> m () #

Log a warn level message with the given source.

Since: 0.0.0.0

logErrorS :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => LogSource -> Utf8Builder -> m () #

Log an error level message with the given source.

Since: 0.0.0.0

logOtherS #

Arguments

:: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) |
=> Text | level
-> LogSource |
-> Utf8Builder |
-> m () |

Log a message with the specified textual level and the given source.

Since: 0.0.0.0

logGeneric :: (MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) => LogSource -> LogLevel -> Utf8Builder -> m () #

Generic, basic function for creating other logging functions.

Since: 0.0.0.0

mkLogFunc :: (CallStack -> LogSource -> LogLevel -> Utf8Builder -> IO ()) -> LogFunc #

Create a `LogFunc` from the given function.

Since: 0.0.0.0

logOptionsMemory :: MonadIO m => m (IORef Builder, LogOptions) #

Create a `LogOptions` value which will store its data in memory. This is primarily intended for testing purposes. This will return both a `LogOptions` value and an `IORef` containing the resulting `Builder` value.

This will default to non-verbose settings and assume there is a terminal attached. These assumptions can be overridden using the appropriate `set` functions.

Since: 0.0.0.0

data LogLevel #

The log level of a message.

Since: 0.0.0.0

Constructors

LevelDebug |
LevelInfo |
LevelWarn |
LevelError |
LevelOther !Text |

#### Instances

Instances details

Read LogLevel # |
Instance details Defined in RIO.Prelude.Logger Methods readsPrec :: Int -> ReadS LogLevel # readList :: ReadS [LogLevel] # readPrec :: ReadPrec LogLevel # readListPrec :: ReadPrec [LogLevel] #
Show LogLevel # |
Instance details Defined in RIO.Prelude.Logger Methods showsPrec :: Int -> LogLevel -> ShowS # show :: LogLevel -> String # showList :: [LogLevel] -> ShowS #
Eq LogLevel # |
Instance details Defined in RIO.Prelude.Logger Methods (==) :: LogLevel -> LogLevel -> Bool # (/=) :: LogLevel -> LogLevel -> Bool #
Ord LogLevel # |
Instance details Defined in RIO.Prelude.Logger Methods compare :: LogLevel -> LogLevel -> Ordering # (<) :: LogLevel -> LogLevel -> Bool # (<=) :: LogLevel -> LogLevel -> Bool # (>) :: LogLevel -> LogLevel -> Bool # (>=) :: LogLevel -> LogLevel -> Bool # max :: LogLevel -> LogLevel -> LogLevel # min :: LogLevel -> LogLevel -> LogLevel #

type LogSource = Text #

Where in the application a log message came from. Used for display purposes only.

Since: 0.0.0.0

displayCallStack :: CallStack -> Utf8Builder #

Convert a `CallStack` value into a `Utf8Builder` indicating the first source location.

TODO Consider showing the entire call stack instead.

Since: 0.0.0.0

noLogging :: (HasLogFunc env, MonadReader env m) => m a -> m a #

Disable logging capabilities in a given sub-routine

Intended to skip logging in general purpose implementations, where secrets might be logged accidently.

Since: 0.1.5.0

logFuncUseColorL :: HasLogFunc env => SimpleGetter env Bool #

Is the log func configured to use color output?

Intended for use by code which wants to optionally add additional color to its log messages.

Since: 0.1.0.0

logFuncLogLevelColorsL :: HasLogFunc env => SimpleGetter env (LogLevel -> Utf8Builder) #

What color is the log func configured to use for each `LogLevel`?

Intended for use by code which wants to optionally add additional color to its log messages.

Since: 0.1.18.0

logFuncSecondaryColorL :: HasLogFunc env => SimpleGetter env Utf8Builder #

What color is the log func configured to use for secondary content?

Intended for use by code which wants to optionally add additional color to its log messages.

Since: 0.1.18.0

logFuncAccentColorsL :: HasLogFunc env => SimpleGetter env (Int -> Utf8Builder) #

What accent colors, indexed by `Int`, is the log func configured to use?

Intended for use by code which wants to optionally add additional color to its log messages.

Since: 0.1.18.0

glog :: (MonadIO m, HasCallStack, HasGLogFunc env, MonadReader env m) => GMsg env -> m () #

Log a value generically.

Since: 0.1.13.0

data GLogFunc msg #

A generic logger of some type `msg`.

Your `GLocFunc` can re-use the existing classical logging framework of RIO, and/or implement additional transforms, filters. Alternatively, you may log to a JSON source in a database, or anywhere else as needed. You can decide how to log levels or severities based on the constructors in your type. You will normally determine this in your main app entry point.

Since: 0.1.13.0

#### Instances

Instances details

Contravariant GLogFunc # | Use this instance to wrap sub-loggers via `mapRIO`. The `Contravariant` class is available in base 4.12.0. Since: 0.1.13.0
Instance details Defined in RIO.Prelude.Logger Methods contramap :: (a' -> a) -> GLogFunc a -> GLogFunc a' # (>$) :: b -> GLogFunc b -> GLogFunc a #
Monoid (GLogFunc msg) # | `mempty` peforms no logging. Since: 0.1.13.0
Instance details Defined in RIO.Prelude.Logger Methods mempty :: GLogFunc msg # mappend :: GLogFunc msg -> GLogFunc msg -> GLogFunc msg # mconcat :: [GLogFunc msg] -> GLogFunc msg #
Semigroup (GLogFunc msg) # | Perform both sets of actions per log entry. Since: 0.1.13.0
Instance details Defined in RIO.Prelude.Logger Methods (<>) :: GLogFunc msg -> GLogFunc msg -> GLogFunc msg # sconcat :: NonEmpty (GLogFunc msg) -> GLogFunc msg # stimes :: Integral b => b -> GLogFunc msg -> GLogFunc msg #
HasGLogFunc (GLogFunc msg) # | Quick way to run a RIO that only has a logger in its environment. Since: 0.1.13.0

Instance details

Defined in RIO.Prelude.Logger

Associated Types

type GMsg (GLogFunc msg) |
Instance details Defined in RIO.Prelude.Logger type GMsg (GLogFunc msg) = msg

Methods

gLogFuncL :: Lens' (GLogFunc msg) (GLogFunc (GMsg (GLogFunc msg))) #

type GMsg (GLogFunc msg) # |
Instance details Defined in RIO.Prelude.Logger type GMsg (GLogFunc msg) = msg

gLogFuncClassic :: (HasLogLevel msg, HasLogSource msg, Display msg) => LogFunc -> GLogFunc msg #

Make a `GLogFunc` via classic `LogFunc`. Use this if you'd like to log your generic data type via the classic RIO terminal logger.

Since: 0.1.13.0

mkGLogFunc :: (CallStack -> msg -> IO ()) -> GLogFunc msg #

Make a custom generic logger. With this you could, for example, write to a database or a log digestion service. For example:

    mkGLogFunc (\stack msg -> send (Data.Aeson.encode (JsonLog stack msg)))

Since: 0.1.13.0

contramapMaybeGLogFunc :: (a -> Maybe b) -> GLogFunc b -> GLogFunc a #

A vesion of `contramapMaybeGLogFunc` which supports filering.

Since: 0.1.13.0

contramapGLogFunc :: (a -> b) -> GLogFunc b -> GLogFunc a #

A contramap. Use this to wrap sub-loggers via `mapRIO`.

If you are on base > 4.12.0, you can just use `contramap`.

Since: 0.1.13.0

class HasGLogFunc env where #

An app is capable of generic logging if it implements this.

Since: 0.1.13.0

Associated Types

type GMsg env #

Methods

gLogFuncL :: Lens' env (GLogFunc (GMsg env)) #

#### Instances

Instances details

HasGLogFunc (GLogFunc msg) # | Quick way to run a RIO that only has a logger in its environment. Since: 0.1.13.0

Instance details

Defined in RIO.Prelude.Logger

Associated Types

type GMsg (GLogFunc msg) |
Instance details Defined in RIO.Prelude.Logger type GMsg (GLogFunc msg) = msg

Methods

gLogFuncL :: Lens' (GLogFunc msg) (GLogFunc (GMsg (GLogFunc msg))) #

class HasLogLevel msg where #

Level, if any, of your logs. If unknown, use `LogOther`. Use for your generic log data types that want to sit inside the classic log framework.

Since: 0.1.13.0

Methods

getLogLevel :: msg -> LogLevel #

class HasLogSource msg where #

Source of a log. This can be whatever you want. Use for your generic log data types that want to sit inside the classic log framework.

Since: 0.1.13.0

Methods

getLogSource :: msg -> LogSource #

type family GMsg env #

#### Instances

Instances details

type GMsg (GLogFunc msg) # |
Instance details Defined in RIO.Prelude.Logger type GMsg (GLogFunc msg) = msg

# Display

class Display a where #

A typeclass for values which can be converted to a `Utf8Builder`. The intention of this typeclass is to provide a human-friendly display of the data.

Since: 0.1.0.0

Minimal complete definition

display | textDisplay

Methods

display :: a -> Utf8Builder #

textDisplay :: a -> Text #

Display data as `Text`, which will also be used for `display` if it is not overriden.

Since: 0.1.7.0

#### Instances

Instances details

Display SomeException # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: SomeException -> Utf8Builder # textDisplay :: SomeException -> Text #
Display IOException # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: IOException -> Utf8Builder # textDisplay :: IOException -> Text #
Display Int16 # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Int16 -> Utf8Builder # textDisplay :: Int16 -> Text #
Display Int32 # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Int32 -> Utf8Builder # textDisplay :: Int32 -> Text #
Display Int64 # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Int64 -> Utf8Builder # textDisplay :: Int64 -> Text #
Display Int8 # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Int8 -> Utf8Builder # textDisplay :: Int8 -> Text #
Display Word16 # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Word16 -> Utf8Builder # textDisplay :: Word16 -> Text #
Display Word32 # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Word32 -> Utf8Builder # textDisplay :: Word32 -> Text #
Display Word64 # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Word64 -> Utf8Builder # textDisplay :: Word64 -> Text #
Display Word8 # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Word8 -> Utf8Builder # textDisplay :: Word8 -> Text #
Display Utf8Builder # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Utf8Builder -> Utf8Builder # textDisplay :: Utf8Builder -> Text #
Display Text # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Text -> Utf8Builder # textDisplay :: Text -> Text #
Display Text # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Text -> Utf8Builder # textDisplay :: Text -> Text #
Display Integer # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Integer -> Utf8Builder # textDisplay :: Integer -> Text #
Display Char # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Char -> Utf8Builder # textDisplay :: Char -> Text #
Display Double # |
Instance details Defined in RIO.Prelude.Display Methods display :: Double -> Utf8Builder # textDisplay :: Double -> Text #
Display Float # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Float -> Utf8Builder # textDisplay :: Float -> Text #
Display Int # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Int -> Utf8Builder # textDisplay :: Int -> Text #
Display Word # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Word -> Utf8Builder # textDisplay :: Word -> Text #
Display (ProcessConfig a b c) # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: ProcessConfig a b c -> Utf8Builder # textDisplay :: ProcessConfig a b c -> Text #

newtype Utf8Builder #

A builder of binary data, with the invariant that the underlying data is supposed to be UTF-8 encoded.

Since: 0.1.0.0

Constructors

Utf8Builder |

Fields

- getUtf8Builder :: Builder

#### Instances

Instances details

Monoid Utf8Builder # |
Instance details Defined in RIO.Prelude.Display Methods mempty :: Utf8Builder # mappend :: Utf8Builder -> Utf8Builder -> Utf8Builder # mconcat :: [Utf8Builder] -> Utf8Builder #
Semigroup Utf8Builder # |
Instance details Defined in RIO.Prelude.Display Methods (<>) :: Utf8Builder -> Utf8Builder -> Utf8Builder # sconcat :: NonEmpty Utf8Builder -> Utf8Builder # stimes :: Integral b => b -> Utf8Builder -> Utf8Builder #
IsString Utf8Builder # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods fromString :: String -> Utf8Builder #
Display Utf8Builder # | Since: 0.1.0.0
Instance details Defined in RIO.Prelude.Display Methods display :: Utf8Builder -> Utf8Builder # textDisplay :: Utf8Builder -> Text #

displayShow :: Show a => a -> Utf8Builder #

Use the `Show` instance for a value to convert it to a `Utf8Builder`.

Since: 0.1.0.0

utf8BuilderToText :: Utf8Builder -> Text #

Convert a `Utf8Builder` value into a strict `Text`.

Since: 0.1.0.0

utf8BuilderToLazyText :: Utf8Builder -> Text #

Convert a `Utf8Builder` value into a lazy `Text`.

Since: 0.1.0.0

displayBytesUtf8 :: ByteString -> Utf8Builder #

Convert a `ByteString` into a `Utf8Builder`.

NOTE This function performs no checks to ensure that the data is, in fact, UTF8 encoded. If you provide non-UTF8 data, later functions may fail.

Since: 0.1.0.0

writeFileUtf8Builder :: MonadIO m => FilePath -> Utf8Builder -> m () #

Write the given `Utf8Builder` value to a file.

Since: 0.1.0.0

# Optics

`microlens`-based Lenses, Traversals, etc.

to :: (s -> a) -> SimpleGetter s a #

`to` creates a getter from any function:

    a ^. to f = f a

It's most useful in chains, because it lets you mix lenses and ordinary functions. Suppose you have a record which comes from some third-party library and doesn't have any lens accessors. You want to do something like this:

    value ^. _1 . field . at 2

However, `field` isn't a getter, and you have to do this instead:

    field (value ^. _1) ^. at 2

but now `value` is in the middle and it's hard to read the resulting code. A variant with `to` is prettier and more readable:

    value ^. _1 . to field . at 2

(^.) :: s -> Getting a s a -> a infixl 8 #

(`^.`) applies a getter to a value; in other words, it gets a value out of a structure using a getter (which can be a lens, traversal, fold, etc.).

Getting 1st field of a tuple:

    (^. _1) :: (a, b) -> a
    (^. _1) = fst

When (`^.`) is used with a traversal, it combines all results using the `Monoid` instance for the resulting type. For instance, for lists it would be simple concatenation:

    >>> ("str","ing") ^. each
    "string"

The reason for this is that traversals use `Applicative`, and the `Applicative` instance for `Const` uses monoid concatenation to combine “effects” of `Const`.

A non-operator version of (`^.`) is called `view`, and it's a bit more general than (`^.`) (it works in `MonadReader`). If you need the general version, you can get it from microlens-mtl; otherwise there's `view` available in Lens.Micro.Extras.

(^..) :: s -> Getting (Endo [a]) s a -> [a] infixl 8 #

`s ^.. t` returns the list of all values that `t` gets from `s`.

A `Maybe` contains either 0 or 1 values:

    >>> Just 3 ^.. _Just
    [3]

Gathering all values in a list of tuples:

    >>> [(1,2),(3,4)] ^.. each.each
    [1,2,3,4]

(^?) :: s -> Getting (First a) s a -> Maybe a infixl 8 #

`s ^? t` returns the 1st element `t` returns, or `Nothing` if `t` doesn't return anything. It's trivially implemented by passing the `First` monoid to the getter.

Safe `head`:

    >>> [] ^? each
    Nothing

    >>> [1..3] ^? each
    Just 1

Converting `Either` to `Maybe`:

    >>> Left 1 ^? _Right
    Nothing

    >>> Right 1 ^? _Right
    Just 1

A non-operator version of (`^?`) is called `preview`, and – like `view` – it's a bit more general than (`^?`) (it works in `MonadReader`). If you need the general version, you can get it from microlens-mtl; otherwise there's `preview` available in Lens.Micro.Extras.

view :: MonadReader s m => Getting a s a -> m a #

`view` is a synonym for (`^.`), generalised for `MonadReader` (we are able to use it instead of (`^.`) since functions are instances of the `MonadReader` class):

    >>> view _1 (1, 2)
    1

When you're using `Reader` for config and your config type has lenses generated for it, most of the time you'll be using `view` instead of `asks`:

    doSomething :: (MonadReader Config m) => m Int
    doSomething = do
      thingy        <- view setting1  -- same as “asks (^. setting1)”
      anotherThingy <- view setting2
      ...

(.~) :: ASetter s t a b -> b -> s -> t infixr 4 #

(`.~`) assigns a value to the target. It's the same thing as using (`%~`) with `const`:

    l .~ x = l %~ const x

See `set` if you want a non-operator synonym.

Here it is used to change 2 fields of a 3-tuple:

    >>> (0,0,0) & _1 .~ 1 & _3 .~ 3
    (1,0,3)

preview :: MonadReader s m => Getting (First a) s a -> m (Maybe a) #

`preview` is a synonym for (`^?`), generalised for `MonadReader` (just like `view`, which is a synonym for (`^.`)).

    >>> preview each [1..5]
    Just 1

type Lens' s a = Lens s s a a #

This is a type alias for monomorphic lenses which don't change the type of the container (or of the value inside).

type Lens s t a b = forall (f :: Type -> Type). Functor f => (a -> f b) -> s -> f t #

`Lens s t a b` is the lowest common denominator of a setter and a getter, something that has the power of both; it has a `Functor` constraint, and since both `Const` and `Identity` are functors, it can be used whenever a getter or a setter is needed.

- `a` is the type of the value inside of structure
- `b` is the type of the replaced value
- `s` is the type of the whole structure
- `t` is the type of the structure after replacing `a` in it with `b`

type Getting r s a = (a -> Const r a) -> s -> Const r s #

Functions that operate on getters and folds – such as (`^.`), (`^..`), (`^?`) – use `Getter r s a` (with different values of `r`) to describe what kind of result they need. For instance, (`^.`) needs the getter to be able to return a single value, and so it accepts a getter of type `Getting a s a`. (`^..`) wants the getter to gather values together, so it uses `Getting (Endo [a]) s a` (it could've used `Getting [a] s a` instead, but it's faster with `Endo`). The choice of `r` depends on what you want to do with elements you're extracting from `s`.

type SimpleGetter s a = forall r. Getting r s a #

A `SimpleGetter s a` extracts `a` from `s`; so, it's the same thing as `(s -> a)`, but you can use it in lens chains because its type looks like this:

    type SimpleGetter s a =
      forall r. (a -> Const r a) -> s -> Const r s

Since `Const r` is a functor, `SimpleGetter` has the same shape as other lens types and can be composed with them. To get `(s -> a)` out of a `SimpleGetter`, choose `r ~ a` and feed `Const :: a -> Const a a` to the getter:

    -- the actual signature is more permissive:
    -- view :: Getting a s a -> s -> a
    view :: SimpleGetter s a -> s -> a
    view getter = getConst . getter Const

The actual `Getter` from lens is more general:

    type Getter s a =
      forall f. (Contravariant f, Functor f) => (a -> f a) -> s -> f s

I'm not currently aware of any functions that take lens's `Getter` but won't accept `SimpleGetter`, but you should try to avoid exporting `SimpleGetter`s anyway to minimise confusion. Alternatively, look at microlens-contra, which provides a fully lens-compatible `Getter`.

Lens users: you can convert a `SimpleGetter` to `Getter` by applying `to . view` to it.

type ASetter' s a = ASetter s s a a #

This is a type alias for monomorphic setters which don't change the type of the container (or of the value inside). It's useful more often than the same type in lens, because we can't provide real setters and so it does the job of both `ASetter'` and `Setter'`.

type ASetter s t a b = (a -> Identity b) -> s -> Identity t #

`ASetter s t a b` is something that turns a function modifying a value into a function modifying a structure. If you ignore `Identity` (as `Identity a` is the same thing as `a`), the type is:

    type ASetter s t a b = (a -> b) -> s -> t

The reason `Identity` is used here is for `ASetter` to be composable with other types, such as `Lens`.

Technically, if you're writing a library, you shouldn't use this type for setters you are exporting from your library; the right type to use is `Setter`, but it is not provided by this package (because then it'd have to depend on distributive). It's completely alright, however, to export functions which take an `ASetter` as an argument.

sets :: ((a -> b) -> s -> t) -> ASetter s t a b #

`sets` creates an `ASetter` from an ordinary function. (The only thing it does is wrapping and unwrapping `Identity`.)

(%~) :: ASetter s t a b -> (a -> b) -> s -> t infixr 4 #

(`%~`) applies a function to the target; an alternative explanation is that it is an inverse of `sets`, which turns a setter into an ordinary function. ``mapped` `%~` `reverse`` is the same thing as ``fmap` `reverse``.

See `over` if you want a non-operator synonym.

Negating the 1st element of a pair:

    >>> (1,2) & _1 %~ negate
    (-1,2)

Turning all `Left`s in a list to upper case:

    >>> (mapped._Left.mapped %~ toUpper) [Left "foo", Right "bar"]
    [Left "FOO",Right "bar"]

over :: ASetter s t a b -> (a -> b) -> s -> t #

`over` is a synonym for (`%~`).

Getting `fmap` in a roundabout way:

    over mapped :: Functor f => (a -> b) -> f a -> f b
    over mapped = fmap

Applying a function to both components of a pair:

    over both :: (a -> b) -> (a, a) -> (b, b)
    over both = \f t -> (f (fst t), f (snd t))

Using ``over` `_2`` as a replacement for `second`:

    >>> over _2 show (10,20)
    (10,"20")

set :: ASetter s t a b -> b -> s -> t #

`set` is a synonym for (`.~`).

Setting the 1st component of a pair:

    set _1 :: x -> (a, b) -> (x, b)
    set _1 = \x t -> (x, snd t)

Using it to rewrite (`<$`):

    set mapped :: Functor f => a -> f b -> f a
    set mapped = (<$)

lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b #

`lens` creates a `Lens` from a getter and a setter. The resulting lens isn't the most effective one (because of having to traverse the structure twice when modifying), but it shouldn't matter much.

A (partial) lens for list indexing:

    ix :: Int -> Lens' [a] a
    ix i = lens (!! i)                                   -- getter
                (\s b -> take i s ++ b : drop (i+1) s)   -- setter

Usage:

    >>> [1..9] ^. ix 3
    4

    >>> [1..9] & ix 3 %~ negate
    [1,2,3,-4,5,6,7,8,9]

When getting, the setter is completely unused; when setting, the getter is unused. Both are used only when the value is being modified. For instance, here we define a lens for the 1st element of a list, but instead of a legitimate getter we use `undefined`. Then we use the resulting lens for setting and it works, which proves that the getter wasn't used:

    >>> [1,2,3] & lens undefined (\s b -> b : tail s) .~ 10
    [10,2,3]

# Concurrency

data ThreadId #

A `ThreadId` is an abstract type representing a handle to a thread. `ThreadId` is an instance of `Eq`, `Ord` and `Show`, where the `Ord` instance implements an arbitrary total ordering over `ThreadId`s. The `Show` instance lets you convert an arbitrary-valued `ThreadId` to string form; showing a `ThreadId` value is occasionally useful when debugging or diagnosing the behaviour of a concurrent program.

Note: in GHC, if you have a `ThreadId`, you essentially have a pointer to the thread itself. This means the thread itself can't be garbage collected until you drop the `ThreadId`. This misfeature would be difficult to correct while continuing to support `threadStatus`.

#### Instances

Instances details

NFData ThreadId | Since: deepseq-1.4.0.0
Instance details Defined in Control.DeepSeq Methods rnf :: ThreadId -> () #
Show ThreadId | @since base-4.2.0.0
Instance details Defined in GHC.Internal.Conc.Sync Methods showsPrec :: Int -> ThreadId -> ShowS # show :: ThreadId -> String # showList :: [ThreadId] -> ShowS #
Eq ThreadId | @since base-4.2.0.0
Instance details Defined in GHC.Internal.Conc.Sync Methods (==) :: ThreadId -> ThreadId -> Bool # (/=) :: ThreadId -> ThreadId -> Bool #
Ord ThreadId | @since base-4.2.0.0
Instance details Defined in GHC.Internal.Conc.Sync Methods compare :: ThreadId -> ThreadId -> Ordering # (<) :: ThreadId -> ThreadId -> Bool # (<=) :: ThreadId -> ThreadId -> Bool # (>) :: ThreadId -> ThreadId -> Bool # (>=) :: ThreadId -> ThreadId -> Bool # max :: ThreadId -> ThreadId -> ThreadId # min :: ThreadId -> ThreadId -> ThreadId #
Hashable ThreadId |
Instance details Defined in Data.Hashable.Class Methods hashWithSalt :: Int -> ThreadId -> Int # hash :: ThreadId -> Int #

myThreadId :: MonadIO m => m ThreadId #

Lifted version of `myThreadId`.

Since: unliftio-0.1.1.0

isCurrentThreadBound :: MonadIO m => m Bool #

Lifted version of `isCurrentThreadBound`.

Since: unliftio-0.1.1.0

threadWaitRead :: MonadIO m => Fd -> m () #

Lifted version of `threadWaitRead`.

Since: unliftio-0.1.1.0

threadWaitWrite :: MonadIO m => Fd -> m () #

Lifted version of `threadWaitWrite`.

Since: unliftio-0.1.1.0

threadDelay :: MonadIO m => Int -> m () #

Lifted version of `threadDelay`.

Since: unliftio-0.1.1.0

yieldThread :: MonadIO m => m () #

## Async

module UnliftIO.Async

## STM

module UnliftIO.STM

## Chan

module UnliftIO.Chan

## Timeout

module UnliftIO.Timeout

# Exceptions

module UnliftIO.Exception

Re-exported from Control.Monad.Catch:

throwM :: (MonadThrow m, HasCallStack, Exception e) => e -> m a #

Throw an exception. Note that this throws when this action is run in the monad `m`, not when it is applied. It is a generalization of Control.Exception's `throwIO`.

Should satisfy the law:

    throwM e >> f = throwM e

# Files and handles

module UnliftIO.IO

module UnliftIO.Temporary

hPutBuilder :: MonadIO m => Handle -> Builder -> m () #

withLazyFile :: MonadUnliftIO m => FilePath -> (ByteString -> m a) -> m a #

Lazily get the contents of a file. Unlike `readFile`, this ensures that if an exception is thrown, the file handle is closed immediately.

withLazyFileUtf8 :: MonadUnliftIO m => FilePath -> (Text -> m a) -> m a #

Lazily read a file in UTF8 encoding.

Since: 0.1.13

readFileBinary :: MonadIO m => FilePath -> m ByteString #

Same as `readFile`, but generalized to `MonadIO`

writeFileBinary :: MonadIO m => FilePath -> ByteString -> m () #

Same as `writeFile`, but generalized to `MonadIO`

readFileUtf8 :: MonadIO m => FilePath -> m Text #

Read a file in UTF8 encoding, throwing an exception on invalid character encoding.

This function will use OS-specific line ending handling.

writeFileUtf8 :: MonadIO m => FilePath -> Text -> m () #

Write a file in UTF8 encoding

This function will use OS-specific line ending handling.

# Exit

data ExitCode #

Defines the exit codes that a program can return.

Constructors

ExitSuccess | indicates successful termination;
ExitFailure Int | indicates program failure with an exit code. The exact interpretation of the code is operating-system dependent. In particular, some values may be prohibited (e.g. 0 on a POSIX-compliant system).

#### Instances

Instances details

NFData ExitCode | Since: deepseq-1.4.2.0
Instance details Defined in Control.DeepSeq Methods rnf :: ExitCode -> () #
Exception ExitCode | @since base-4.1.0.0
Instance details Defined in GHC.Internal.IO.Exception Methods toException :: ExitCode -> SomeException # fromException :: SomeException -> Maybe ExitCode # displayException :: ExitCode -> String # backtraceDesired :: ExitCode -> Bool #
Generic ExitCode |

Instance details

Defined in GHC.Internal.IO.Exception

Associated Types

type Rep ExitCode |
Instance details Defined in GHC.Internal.IO.Exception type Rep ExitCode = D1 ('MetaData "ExitCode" "GHC.Internal.IO.Exception" "ghc-internal" 'False) (C1 ('MetaCons "ExitSuccess" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "ExitFailure" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int)))

Methods

from :: ExitCode -> Rep ExitCode x #

to :: Rep ExitCode x -> ExitCode #

Read ExitCode |
Instance details Defined in GHC.Internal.IO.Exception Methods readsPrec :: Int -> ReadS ExitCode # readList :: ReadS [ExitCode] # readPrec :: ReadPrec ExitCode # readListPrec :: ReadPrec [ExitCode] #
Show ExitCode |
Instance details Defined in GHC.Internal.IO.Exception Methods showsPrec :: Int -> ExitCode -> ShowS # show :: ExitCode -> String # showList :: [ExitCode] -> ShowS #
Eq ExitCode |
Instance details Defined in GHC.Internal.IO.Exception Methods (==) :: ExitCode -> ExitCode -> Bool # (/=) :: ExitCode -> ExitCode -> Bool #
Ord ExitCode |
Instance details Defined in GHC.Internal.IO.Exception Methods compare :: ExitCode -> ExitCode -> Ordering # (<) :: ExitCode -> ExitCode -> Bool # (<=) :: ExitCode -> ExitCode -> Bool # (>) :: ExitCode -> ExitCode -> Bool # (>=) :: ExitCode -> ExitCode -> Bool # max :: ExitCode -> ExitCode -> ExitCode # min :: ExitCode -> ExitCode -> ExitCode #
type Rep ExitCode |
Instance details Defined in GHC.Internal.IO.Exception type Rep ExitCode = D1 ('MetaData "ExitCode" "GHC.Internal.IO.Exception" "ghc-internal" 'False) (C1 ('MetaCons "ExitSuccess" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "ExitFailure" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int)))

exitWith :: MonadIO m => ExitCode -> m a #

Lifted version of "System.Exit.exitWith".

@since 0.1.9.0.

exitFailure :: MonadIO m => m a #

Lifted version of "System.Exit.exitFailure".

@since 0.1.9.0.

exitSuccess :: MonadIO m => m a #

Lifted version of "System.Exit.exitSuccess".

@since 0.1.9.0.

# Mutable Variables

## SomeRef

data SomeRef a #

Abstraction over how to read from and write to a mutable reference

Since: 0.1.4.0

#### Instances

Instances details

HasStateRef a (SomeRef a) # | Identity state reference where the SomeRef is the env Since: 0.1.4.0
Instance details Defined in RIO.Prelude.RIO Methods stateRefL :: Lens' (SomeRef a) (SomeRef a) #
HasWriteRef a (SomeRef a) # | Identity write reference where the SomeRef is the env Since: 0.1.4.0
Instance details Defined in RIO.Prelude.RIO Methods writeRefL :: Lens' (SomeRef a) (SomeRef a) #

mapRIO :: (outer -> inner) -> RIO inner a -> RIO outer a #

Lift one RIO env to another.

Since: 0.1.13.0

class HasStateRef s env | env -> s where #

Environment values with stateful capabilities to SomeRef

Since: 0.1.4.0

Methods

stateRefL :: Lens' env (SomeRef s) #

#### Instances

Instances details

HasStateRef a (SomeRef a) # | Identity state reference where the SomeRef is the env Since: 0.1.4.0
Instance details Defined in RIO.Prelude.RIO Methods stateRefL :: Lens' (SomeRef a) (SomeRef a) #

class HasWriteRef w env | env -> w where #

Environment values with writing capabilities to SomeRef

Since: 0.1.4.0

Methods

writeRefL :: Lens' env (SomeRef w) #

#### Instances

Instances details

HasWriteRef a (SomeRef a) # | Identity write reference where the SomeRef is the env Since: 0.1.4.0
Instance details Defined in RIO.Prelude.RIO Methods writeRefL :: Lens' (SomeRef a) (SomeRef a) #

newSomeRef :: MonadIO m => a -> m (SomeRef a) #

create a new boxed SomeRef

Since: 0.1.4.0

newUnboxedSomeRef :: (MonadIO m, Unbox a) => a -> m (SomeRef a) #

create a new unboxed SomeRef

Since: 0.1.4.0

readSomeRef :: MonadIO m => SomeRef a -> m a #

Read from a SomeRef

Since: 0.1.4.0

writeSomeRef :: MonadIO m => SomeRef a -> a -> m () #

Write to a SomeRef

Since: 0.1.4.0

modifySomeRef :: MonadIO m => SomeRef a -> (a -> a) -> m () #

Modify a SomeRef This function is subject to change due to the lack of atomic operations

Since: 0.1.4.0

## URef

data URef s a #

An unboxed reference. This works like an `IORef`, but the data is stored in a bytearray instead of a heap object, avoiding significant allocation overhead in some cases. For a concrete example, see this Stack Overflow question: https://stackoverflow.com/questions/27261813/why-is-my-little-stref-int-require-allocating-gigabytes.

The first parameter is the state token type, the same as would be used for the `ST` monad. If you're using an `IO`-based monad, you can use the convenience `IOURef` type synonym instead.

Since: 0.0.2.0

type IOURef = URef (PrimState IO) #

Helpful type synonym for using a `URef` from an `IO`-based stack.

Since: 0.0.2.0

newURef :: (PrimMonad m, Unbox a) => a -> m (URef (PrimState m) a) #

Create a new `URef`

Since: 0.0.2.0

readURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> m a #

Read the value in a `URef`

Since: 0.0.2.0

writeURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> a -> m () #

Write a value into a `URef`. Note that this action is strict, and will force evalution of the value.

Since: 0.0.2.0

modifyURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> (a -> a) -> m () #

Modify a value in a `URef`. Note that this action is strict, and will force evaluation of the result value.

Since: 0.0.2.0

## IORef

module UnliftIO.IORef

## MVar

module UnliftIO.MVar

## QSem

module UnliftIO.QSem

## QSemN

module UnliftIO.QSemN

## Memoize

module UnliftIO.Memoize

## Deque

module RIO.Deque

# Debugging

trace :: Text -> a -> a #

Warning: Trace statement left in code

Since: 0.1.0.0

traceIO :: MonadIO m => Text -> m () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceMarkerIO :: MonadIO m => Text -> m () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceMarker :: Text -> a -> a #

Warning: Trace statement left in code

Since: 0.1.0.0

traceEventIO :: MonadIO m => Text -> m () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceEvent :: Text -> a -> a #

Warning: Trace statement left in code

Since: 0.1.0.0

traceStack :: Text -> a -> a #

Warning: Trace statement left in code

Since: 0.1.0.0

traceShowM :: (Show a, Applicative f) => a -> f () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceM :: Applicative f => Text -> f () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceShowId :: Show a => a -> a #

Warning: Trace statement left in code

Since: 0.1.0.0

traceShow :: Show a => a -> b -> b #

Warning: Trace statement left in code

Since: 0.1.0.0

traceId :: Text -> Text #

Warning: Trace statement left in code

Since: 0.1.0.0

traceShowIO :: (Show a, MonadIO m) => a -> m () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceShowEvent :: Show a => a -> b -> b #

Warning: Trace statement left in code

Since: 0.1.0.0

traceShowEventIO :: (Show a, MonadIO m) => a -> m () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceShowMarker :: Show a => a -> b -> b #

Warning: Trace statement left in code

Since: 0.1.0.0

traceShowMarkerIO :: (Show a, MonadIO m) => a -> m () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceShowStack :: Show a => a -> b -> b #

Warning: Trace statement left in code

Since: 0.1.0.0

traceDisplay :: Display a => a -> b -> b #

Warning: Trace statement left in code

Since: 0.1.0.0

traceDisplayId :: Display a => a -> a #

Warning: Trace statement left in code

Since: 0.1.0.0

traceDisplayIO :: (Display a, MonadIO m) => a -> m () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceDisplayM :: (Display a, Applicative f) => a -> f () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceDisplayEvent :: Display a => a -> b -> b #

Warning: Trace statement left in code

Since: 0.1.0.0

traceDisplayEventIO :: (Display a, MonadIO m) => a -> m () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceDisplayMarker :: Display a => a -> b -> b #

Warning: Trace statement left in code

Since: 0.1.0.0

traceDisplayMarkerIO :: (Display a, MonadIO m) => a -> m () #

Warning: Trace statement left in code

Since: 0.1.0.0

traceDisplayStack :: Display a => a -> b -> b #

Warning: Trace statement left in code

Since: 0.1.0.0