Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
-
class
(
MonadAsync
m,
MonadEventlog
m,
MonadFork
m,
MonadST
m,
MonadDelay
m,
MonadThread
m,
MonadThrow
m,
MonadCatch
m,
MonadMask
m,
MonadMonotonicTime
m,
MonadEvaluate
m,
MonadThrow
(
STM
m),
forall
a.
NoThunks
(m a),
forall
a.
NoThunks
a =>
NoThunks
(
StrictTVar
m a),
forall
a.
NoThunks
a =>
NoThunks
(
StrictMVar
m a)) =>
IOLike
m
where
- forgetSignKeyKES :: KESAlgorithm v => SignKeyKES v -> m ()
-
class
(
Typeable
e,
Show
e) =>
Exception
e
where
- toException :: e -> SomeException
- fromException :: SomeException -> Maybe e
- displayException :: e -> String
- data ExitCase a
-
class
MonadThrow
m =>
MonadCatch
(m ::
Type
->
Type
)
where
- catch :: Exception e => m a -> (e -> m a) -> m a
- catchJust :: Exception e => (e -> Maybe b) -> m a -> (b -> m a) -> m a
- try :: Exception e => m a -> m ( Either e a)
- tryJust :: Exception e => (e -> Maybe b) -> m a -> m ( Either b a)
- handle :: Exception e => (e -> m a) -> m a -> m a
- handleJust :: Exception e => (e -> Maybe b) -> (b -> m a) -> m a -> m a
- onException :: m a -> m b -> m a
- bracketOnError :: m a -> (a -> m b) -> (a -> m c) -> m c
- generalBracket :: m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c)
-
class
MonadCatch
m =>
MonadMask
(m ::
Type
->
Type
)
where
- mask :: (( forall a. m a -> m a) -> m b) -> m b
- uninterruptibleMask :: (( forall a. m a -> m a) -> m b) -> m b
- mask_ :: m a -> m a
- uninterruptibleMask_ :: m a -> m a
- class Monad m => MonadThrow (m :: Type -> Type ) where
- data SomeException
- module Ouroboros.Consensus.Util.MonadSTM.NormalForm
-
class
MonadThread
m =>
MonadFork
(m ::
Type
->
Type
)
where
- forkIO :: m () -> m ( ThreadId m)
- forkIOWithUnmask :: (( forall a. m a -> m a) -> m ()) -> m ( ThreadId m)
- throwTo :: Exception e => ThreadId m -> e -> m ()
- killThread :: ThreadId m -> m ()
- yield :: m ()
-
class
(
Monad
m,
Eq
(
ThreadId
m),
Ord
(
ThreadId
m),
Show
(
ThreadId
m)) =>
MonadThread
(m ::
Type
->
Type
)
where
- type ThreadId (m :: Type -> Type )
- myThreadId :: m ( ThreadId m)
- labelThread :: ThreadId m -> String -> m ()
- labelThisThread :: MonadThread m => String -> m ()
- data ExceptionInLinkedThread = ExceptionInLinkedThread String SomeException
-
class
(
MonadSTM
m,
MonadThread
m) =>
MonadAsync
(m ::
Type
->
Type
)
where
- type Async (m :: Type -> Type ) = (async :: Type -> Type ) | async -> m
- async :: m a -> m ( Async m a)
- asyncThreadId :: Async m a -> ThreadId m
- withAsync :: m a -> ( Async m a -> m b) -> m b
- waitSTM :: Async m a -> STM m a
- pollSTM :: Async m a -> STM m ( Maybe ( Either SomeException a))
- waitCatchSTM :: Async m a -> STM m ( Either SomeException a)
- waitAnySTM :: [ Async m a] -> STM m ( Async m a, a)
- waitAnyCatchSTM :: [ Async m a] -> STM m ( Async m a, Either SomeException a)
- waitEitherSTM :: Async m a -> Async m b -> STM m ( Either a b)
- waitEitherSTM_ :: Async m a -> Async m b -> STM m ()
- waitEitherCatchSTM :: Async m a -> Async m b -> STM m ( Either ( Either SomeException a) ( Either SomeException b))
- waitBothSTM :: Async m a -> Async m b -> STM m (a, b)
- wait :: Async m a -> m a
- poll :: Async m a -> m ( Maybe ( Either SomeException a))
- waitCatch :: Async m a -> m ( Either SomeException a)
- cancel :: Async m a -> m ()
- cancelWith :: Exception e => Async m a -> e -> m ()
- uninterruptibleCancel :: Async m a -> m ()
- waitAny :: [ Async m a] -> m ( Async m a, a)
- waitAnyCatch :: [ Async m a] -> m ( Async m a, Either SomeException a)
- waitAnyCancel :: [ Async m a] -> m ( Async m a, a)
- waitAnyCatchCancel :: [ Async m a] -> m ( Async m a, Either SomeException a)
- waitEither :: Async m a -> Async m b -> m ( Either a b)
- waitEitherCatch :: Async m a -> Async m b -> m ( Either ( Either SomeException a) ( Either SomeException b))
- waitEitherCancel :: Async m a -> Async m b -> m ( Either a b)
- waitEitherCatchCancel :: Async m a -> Async m b -> m ( Either ( Either SomeException a) ( Either SomeException b))
- waitEither_ :: Async m a -> Async m b -> m ()
- waitBoth :: Async m a -> Async m b -> m (a, b)
- race :: m a -> m b -> m ( Either a b)
- race_ :: m a -> m b -> m ()
- concurrently :: m a -> m b -> m (a, b)
- concurrently_ :: m a -> m b -> m ()
- asyncWithUnmask :: (( forall b. m b -> m b) -> m a) -> m ( Async m a)
- link :: ( MonadAsync m, MonadFork m, MonadMask m) => Async m a -> m ()
- linkTo :: ( MonadAsync m, MonadFork m, MonadMask m) => ThreadId m -> Async m a -> m ()
-
class
Monad
m =>
MonadST
(m ::
Type
->
Type
)
where
- withLiftST :: ( forall s. ( forall a. ST s a -> m a) -> b) -> b
- data DiffTime
-
class
Monad
m =>
MonadMonotonicTime
(m ::
Type
->
Type
)
where
- getMonotonicTime :: m Time
- newtype Time = Time DiffTime
- addTime :: DiffTime -> Time -> Time
- diffTime :: Time -> Time -> DiffTime
-
class
Monad
m =>
MonadDelay
(m ::
Type
->
Type
)
where
- threadDelay :: DiffTime -> m ()
-
class
Monad
m =>
MonadEventlog
(m ::
Type
->
Type
)
where
- traceEventIO :: String -> m ()
- traceMarkerIO :: String -> m ()
-
class
MonadThrow
m =>
MonadEvaluate
(m ::
Type
->
Type
)
where
- evaluate :: a -> m a
- class NoThunks a where
Documentation
class ( MonadAsync m, MonadEventlog m, MonadFork m, MonadST m, MonadDelay m, MonadThread m, MonadThrow m, MonadCatch m, MonadMask m, MonadMonotonicTime m, MonadEvaluate m, MonadThrow ( STM m), forall a. NoThunks (m a), forall a. NoThunks a => NoThunks ( StrictTVar m a), forall a. NoThunks a => NoThunks ( StrictMVar m a)) => IOLike m where Source #
forgetSignKeyKES :: KESAlgorithm v => SignKeyKES v -> m () Source #
Securely forget a KES signing key.
No-op for the IOSim, but
forgetSignKeyKES
for IO.
Instances
IOLike IO Source # | |
Defined in Ouroboros.Consensus.Util.IOLike forgetSignKeyKES :: KESAlgorithm v => SignKeyKES v -> IO () Source # |
|
( IOLike m, forall a. NoThunks ( StrictTVar ( WithEarlyExit m) a), forall a. NoThunks ( StrictMVar ( WithEarlyExit m) a), MonadCatch ( STM m)) => IOLike ( WithEarlyExit m) Source # | |
Defined in Ouroboros.Consensus.Util.EarlyExit forgetSignKeyKES :: KESAlgorithm v => SignKeyKES v -> WithEarlyExit m () Source # |
Re-exports
MonadThrow
class ( Typeable e, Show e) => Exception e where Source #
Any type that you wish to throw or catch as an exception must be an
instance of the
Exception
class. The simplest case is a new exception
type directly below the root:
data MyException = ThisException | ThatException deriving Show instance Exception MyException
The default method definitions in the
Exception
class do what we need
in this case. You can now throw and catch
ThisException
and
ThatException
as exceptions:
*Main> throw ThisException `catch` \e -> putStrLn ("Caught " ++ show (e :: MyException)) Caught ThisException
In more complicated examples, you may wish to define a whole hierarchy of exceptions:
--------------------------------------------------------------------- -- Make the root exception type for all the exceptions in a compiler data SomeCompilerException = forall e . Exception e => SomeCompilerException e instance Show SomeCompilerException where show (SomeCompilerException e) = show e instance Exception SomeCompilerException compilerExceptionToException :: Exception e => e -> SomeException compilerExceptionToException = toException . SomeCompilerException compilerExceptionFromException :: Exception e => SomeException -> Maybe e compilerExceptionFromException x = do SomeCompilerException a <- fromException x cast a --------------------------------------------------------------------- -- Make a subhierarchy for exceptions in the frontend of the compiler data SomeFrontendException = forall e . Exception e => SomeFrontendException e instance Show SomeFrontendException where show (SomeFrontendException e) = show e instance Exception SomeFrontendException where toException = compilerExceptionToException fromException = compilerExceptionFromException frontendExceptionToException :: Exception e => e -> SomeException frontendExceptionToException = toException . SomeFrontendException frontendExceptionFromException :: Exception e => SomeException -> Maybe e frontendExceptionFromException x = do SomeFrontendException a <- fromException x cast a --------------------------------------------------------------------- -- Make an exception type for a particular frontend compiler exception data MismatchedParentheses = MismatchedParentheses deriving Show instance Exception MismatchedParentheses where toException = frontendExceptionToException fromException = frontendExceptionFromException
We can now catch a
MismatchedParentheses
exception as
MismatchedParentheses
,
SomeFrontendException
or
SomeCompilerException
, but not other types, e.g.
IOException
:
*Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: MismatchedParentheses)) Caught MismatchedParentheses *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeFrontendException)) Caught MismatchedParentheses *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeCompilerException)) Caught MismatchedParentheses *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: IOException)) *** Exception: MismatchedParentheses
Nothing
toException :: e -> SomeException Source #
fromException :: SomeException -> Maybe e Source #
displayException :: e -> String Source #
Render this exception value in a human-friendly manner.
Default implementation:
.
show
Since: base-4.8.0.0
Instances
Used in
generalBracket
See
exceptions
package for discussion and motivation.
class MonadThrow m => MonadCatch (m :: Type -> Type ) where Source #
Catching exceptions.
Covers standard utilities to respond to exceptions.
catch :: Exception e => m a -> (e -> m a) -> m a Source #
catchJust :: Exception e => (e -> Maybe b) -> m a -> (b -> m a) -> m a Source #
try :: Exception e => m a -> m ( Either e a) Source #
tryJust :: Exception e => (e -> Maybe b) -> m a -> m ( Either b a) Source #
handle :: Exception e => (e -> m a) -> m a -> m a Source #
handleJust :: Exception e => (e -> Maybe b) -> (b -> m a) -> m a -> m a Source #
onException :: m a -> m b -> m a Source #
bracketOnError :: m a -> (a -> m b) -> (a -> m c) -> m c Source #
generalBracket :: m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c) Source #
General form of bracket
See http://hackage.haskell.org/package/exceptions-0.10.0/docs/Control-Monad-Catch.html#v:generalBracket for discussion and motivation.
Instances
class MonadCatch m => MonadMask (m :: Type -> Type ) where Source #
Support for safely working in the presence of asynchronous exceptions.
This is typically not needed directly as the utilities in
MonadThrow
and
MonadCatch
cover most use cases.
mask :: (( forall a. m a -> m a) -> m b) -> m b Source #
uninterruptibleMask :: (( forall a. m a -> m a) -> m b) -> m b Source #
uninterruptibleMask_ :: m a -> m a Source #
Instances
class Monad m => MonadThrow (m :: Type -> Type ) where Source #
Throwing exceptions, and resource handling in the presence of exceptions.
Does not include the ability to respond to exceptions.
throwIO :: Exception e => e -> m a Source #
bracket :: m a -> (a -> m b) -> (a -> m c) -> m c Source #
Instances
data SomeException Source #
The
SomeException
type is the root of the exception type hierarchy.
When an exception of type
e
is thrown, behind the scenes it is
encapsulated in a
SomeException
.
Instances
Show SomeException |
Since: base-3.0 |
Defined in GHC.Exception.Type |
|
Exception SomeException |
Since: base-3.0 |
Defined in GHC.Exception.Type |
MonadSTM
MonadFork, TODO: Should we hide this in favour of MonadAsync?
class MonadThread m => MonadFork (m :: Type -> Type ) where Source #
forkIO , forkIOWithUnmask , throwTo , yield
forkIO :: m () -> m ( ThreadId m) Source #
forkIOWithUnmask :: (( forall a. m a -> m a) -> m ()) -> m ( ThreadId m) Source #
throwTo :: Exception e => ThreadId m -> e -> m () Source #
killThread :: ThreadId m -> m () Source #
Instances
class ( Monad m, Eq ( ThreadId m), Ord ( ThreadId m), Show ( ThreadId m)) => MonadThread (m :: Type -> Type ) where Source #
myThreadId :: m ( ThreadId m) Source #
labelThread :: ThreadId m -> String -> m () Source #
Instances
MonadThread IO | |
MonadThread m => MonadThread ( WithEarlyExit m) Source # | |
Defined in Ouroboros.Consensus.Util.EarlyExit type ThreadId ( WithEarlyExit m) Source # myThreadId :: WithEarlyExit m ( ThreadId ( WithEarlyExit m)) Source # labelThread :: ThreadId ( WithEarlyExit m) -> String -> WithEarlyExit m () Source # |
|
MonadThread m => MonadThread ( ReaderT r m) | |
labelThisThread :: MonadThread m => String -> m () Source #
Apply the label to the current thread
MonadAsync
data ExceptionInLinkedThread Source #
Exception from child thread re-raised in parent thread
We record the thread ID of the child thread as a
String
. This avoids
an
m
parameter in the type, which is important:
ExceptionInLinkedThread
must be an instance of
Exception
, requiring it to be
Typeable
; if
m
appeared in the type, we would require
m
to be
Typeable
, which does not
work with with the simulator, as it would require a
Typeable
constraint
on the
s
parameter of
IOSim
.
Instances
class ( MonadSTM m, MonadThread m) => MonadAsync (m :: Type -> Type ) where Source #
async , asyncThreadId , cancel , cancelWith , asyncWithUnmask , waitCatchSTM , pollSTM
type Async (m :: Type -> Type ) = (async :: Type -> Type ) | async -> m Source #
An asynchronous action
async :: m a -> m ( Async m a) Source #
asyncThreadId :: Async m a -> ThreadId m Source #
withAsync :: m a -> ( Async m a -> m b) -> m b Source #
waitSTM :: Async m a -> STM m a Source #
pollSTM :: Async m a -> STM m ( Maybe ( Either SomeException a)) Source #
waitCatchSTM :: Async m a -> STM m ( Either SomeException a) Source #
waitAnySTM :: [ Async m a] -> STM m ( Async m a, a) Source #
waitAnyCatchSTM :: [ Async m a] -> STM m ( Async m a, Either SomeException a) Source #
waitEitherSTM :: Async m a -> Async m b -> STM m ( Either a b) Source #
waitEitherSTM_ :: Async m a -> Async m b -> STM m () Source #
waitEitherCatchSTM :: Async m a -> Async m b -> STM m ( Either ( Either SomeException a) ( Either SomeException b)) Source #
waitBothSTM :: Async m a -> Async m b -> STM m (a, b) Source #
wait :: Async m a -> m a Source #
poll :: Async m a -> m ( Maybe ( Either SomeException a)) Source #
waitCatch :: Async m a -> m ( Either SomeException a) Source #
cancel :: Async m a -> m () Source #
cancelWith :: Exception e => Async m a -> e -> m () Source #
uninterruptibleCancel :: Async m a -> m () Source #
waitAny :: [ Async m a] -> m ( Async m a, a) Source #
waitAnyCatch :: [ Async m a] -> m ( Async m a, Either SomeException a) Source #
waitAnyCancel :: [ Async m a] -> m ( Async m a, a) Source #
waitAnyCatchCancel :: [ Async m a] -> m ( Async m a, Either SomeException a) Source #
waitEither :: Async m a -> Async m b -> m ( Either a b) Source #
waitEitherCatch :: Async m a -> Async m b -> m ( Either ( Either SomeException a) ( Either SomeException b)) Source #
Note, IO-based implementations should override the default
implementation. See the
async
package implementation and comments.
http://hackage.haskell.org/package/async-2.2.1/docs/src/Control.Concurrent.Async.html#waitEitherCatch
waitEitherCancel :: Async m a -> Async m b -> m ( Either a b) Source #
waitEitherCatchCancel :: Async m a -> Async m b -> m ( Either ( Either SomeException a) ( Either SomeException b)) Source #
waitEither_ :: Async m a -> Async m b -> m () Source #
waitBoth :: Async m a -> Async m b -> m (a, b) Source #
race :: m a -> m b -> m ( Either a b) Source #
race_ :: m a -> m b -> m () Source #
concurrently :: m a -> m b -> m (a, b) Source #
concurrently_ :: m a -> m b -> m () Source #
asyncWithUnmask :: (( forall b. m b -> m b) -> m a) -> m ( Async m a) Source #
Instances
linkTo :: ( MonadAsync m, MonadFork m, MonadMask m) => ThreadId m -> Async m a -> m () Source #
Generalizion of
link
that links an async to an arbitrary thread.
MonadST
class Monad m => MonadST (m :: Type -> Type ) where Source #
This class is for abstracting over
stToIO
which allows running
ST
actions in
IO
. In this case it is to allow running
ST
actions within
another monad
m
.
The type of
stToIO
is:
stToIO : ST RealWorld a -> IO a
Abstracting over this is tricky because we need to not care about both
the
IO
, and also the
RealWorld
.
A solution is to write an action that is given the
liftST
as an argument
and where that action itself is polymorphic in the
s
parameter. This
allows us to instantiate it with
RealWorld
in the
IO
case, and the local
s
in a case where we are embedding into another
ST
action.
withLiftST :: ( forall s. ( forall a. ST s a -> m a) -> b) -> b Source #
Instances
MonadST IO | |
Defined in Control.Monad.Class.MonadST withLiftST :: ( forall s. ( forall a. ST s a -> IO a) -> b) -> b Source # |
|
MonadST ( ST s) | |
Defined in Control.Monad.Class.MonadST withLiftST :: ( forall s0. ( forall a. ST s0 a -> ST s a) -> b) -> b Source # |
|
MonadST m => MonadST ( WithEarlyExit m) Source # | |
Defined in Ouroboros.Consensus.Util.EarlyExit withLiftST :: ( forall s. ( forall a. ST s a -> WithEarlyExit m a) -> b) -> b Source # |
|
MonadST m => MonadST ( ReaderT r m) | |
Defined in Control.Monad.Class.MonadST withLiftST :: ( forall s. ( forall a. ST s a -> ReaderT r m a) -> b) -> b Source # |
MonadTime
This is a length of time, as measured by a clock. Conversion functions will treat it as seconds. It has a precision of 10^-12 s.
Instances
class Monad m => MonadMonotonicTime (m :: Type -> Type ) where Source #
getMonotonicTime :: m Time Source #
Time in a monotonic clock, with high precision. The epoch for this clock is arbitrary and does not correspond to any wall clock or calendar.
Instances
MonadMonotonicTime IO | |
Defined in Control.Monad.Class.MonadTime |
|
MonadMonotonicTime m => MonadMonotonicTime ( WithEarlyExit m) Source # | |
Defined in Ouroboros.Consensus.Util.EarlyExit |
|
MonadMonotonicTime m => MonadMonotonicTime ( ReaderT r m) | |
Defined in Control.Monad.Class.MonadTime getMonotonicTime :: ReaderT r m Time Source # |
A point in time in a monotonic clock.
The epoch for this clock is arbitrary and does not correspond to any wall
clock or calendar, and is
not guaranteed
to be the same epoch across
program runs. It is represented as the
DiffTime
from this arbitrary epoch.
Instances
Eq Time | |
Ord Time | |
Defined in Control.Monad.Class.MonadTime |
|
Show Time | |
Generic Time | |
NoThunks Time Source # | |
Condense Time Source # | |
SAct ( SuspendDecision Time ) ( Maybe ( PeerState m)) |
Action of
Note:
|
Defined in Ouroboros.Network.Subscription.PeerState |
|
type Rep Time | |
Defined in Control.Monad.Class.MonadTime |
addTime :: DiffTime -> Time -> Time infixr 9 Source #
Add a duration to a point in time, giving another time.
diffTime :: Time -> Time -> DiffTime Source #
The time duration between two points in time (positive or negative).
MonadDelay
class Monad m => MonadDelay (m :: Type -> Type ) where Source #
Nothing
threadDelay :: DiffTime -> m () Source #
Instances
MonadEventlog
class Monad m => MonadEventlog (m :: Type -> Type ) where Source #
traceEventIO :: String -> m () Source #
Emits a message to the eventlog, if eventlog profiling is available and enabled at runtime.
traceMarkerIO :: String -> m () Source #
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.
Instances
MonadEventlog IO | |
Defined in Control.Monad.Class.MonadEventlog traceEventIO :: String -> IO () Source # traceMarkerIO :: String -> IO () Source # |
|
MonadEventlog m => MonadEventlog ( WithEarlyExit m) Source # | |
Defined in Ouroboros.Consensus.Util.EarlyExit traceEventIO :: String -> WithEarlyExit m () Source # traceMarkerIO :: String -> WithEarlyExit m () Source # |
|
MonadEventlog m => MonadEventlog ( ReaderT r m) | |
Defined in Control.Monad.Class.MonadEventlog traceEventIO :: String -> ReaderT r m () Source # traceMarkerIO :: String -> ReaderT r m () Source # |
MonadEvaluate
class MonadThrow m => MonadEvaluate (m :: Type -> Type ) where Source #
Monads which can
evaluate
.
Instances
MonadEvaluate IO | |
Defined in Control.Monad.Class.MonadThrow |
|
( MonadEvaluate m, MonadCatch m) => MonadEvaluate ( WithEarlyExit m) Source # | |
Defined in Ouroboros.Consensus.Util.EarlyExit evaluate :: a -> WithEarlyExit m a Source # |
|
MonadEvaluate m => MonadEvaluate ( ReaderT r m) | |
Defined in Control.Monad.Class.MonadThrow |
NoThunks
class NoThunks a where Source #
Check a value for unexpected thunks
Nothing
noThunks :: Context -> a -> IO ( Maybe ThunkInfo ) Source #
Check if the argument does not contain any unexpected thunks
For most datatypes, we should have that
noThunks ctxt x == Nothing
if and only if
checkContainsThunks x
For some datatypes however, some thunks are expected. For example, the
internal fingertree
Sequence
might contain thunks (this is
important for the asymptotic complexity of this data structure). However,
we should still check that the
values
in the sequence don't contain any
unexpected thunks.
This means that we need to traverse the sequence, which might force some of
the thunks in the tree. In general, it is acceptable for
noThunks
to force such "expected thunks", as long as it always
reports the
unexpected
thunks.
The default implementation of
noThunks
checks that the argument is in
WHNF, and if so, adds the type into the context (using
showTypeOf
), and
calls
wNoThunks
. See
ThunkInfo
for a detailed discussion of the type
context.
See also discussion of caveats listed for
checkContainsThunks
.
wNoThunks :: Context -> a -> IO ( Maybe ThunkInfo ) Source #
Check that the argument is in normal form, assuming it is in WHNF.
The context will already have been extended with the type we're looking at, so all that's left is to look at the thunks inside the type. The default implementation uses GHC Generics to do this.
showTypeOf :: Proxy a -> String Source #
Show type
a
(to add to the context)
We try hard to avoid
Typeable
constraints in this module: there are types
with no
Typeable
instance but with a
NoThunks
instance (most
important example are types such as
ST s
which rely on parametric
polymorphism). By default we should therefore only show the "outer layer";
for example, if we have a type
Seq (ST s ())
then
showTypeOf
should just give
Seq
, leaving it up to the instance for
ST
to decide how to implement
showTypeOf
; this keeps things
compositional. The default implementation does precisely this using the
metadata that GHC Generics provides.
For convenience, however, some of the
deriving via
newtype wrappers we
provide
do
depend on
Typeable
; see below.