Copyright | (c) Alexey Kuleshevich 2020 |
---|---|
License | BSD3 |
Maintainer | Alexey Kuleshevich <[email protected]> |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
Control.Prim.Monad.Unsafe
Contents
Description
Synopsis
- unsafePrim :: MonadPrim s m => (State# s' -> (# State# s', a #)) -> m a
- unsafePrim_ :: MonadPrim s m => (State# s' -> State# s') -> m ()
- unsafePrimBase :: MonadPrimBase s' m => m a -> State# s -> (# State# s, a #)
- unsafePrimBase_ :: MonadPrimBase s' m => m () -> State# s -> State# s
- unsafePrimBaseToPrim :: (MonadPrimBase sn n, MonadPrim sm m) => n a -> m a
- unsafePrimBaseToIO :: MonadPrimBase s m => m a -> IO a
- unsafePrimBaseToST :: MonadPrimBase sm m => m a -> ST s a
- unsafeIOToPrim :: MonadPrim s m => IO a -> m a
- unsafeSTToPrim :: MonadPrim s' m => ST s a -> m a
- unsafeLiftPrimBase :: forall sn n sm m a. (MonadPrimBase sn n, MonadPrim sm m) => n a -> m a
- noDuplicatePrim :: MonadPrim s m => m ()
- unsafeDupablePerformPrimBase :: MonadPrimBase s m => m a -> a
- unsafeInlineIO :: IO a -> a
- unsafeInlineST :: ST s a -> a
- unsafeInlinePrimBase :: MonadPrimBase s m => m a -> a
- unsafeInterleavePrimBase :: MonadPrimBase s m => m a -> m a
- unsafeDupableInterleavePrimBase :: MonadPrimBase s m => m a -> m a
- unsafePerformIO :: IO a -> a
- unsafeDupablePerformIO :: IO a -> a
- unsafeInterleaveIO :: IO a -> IO a
- unsafeDupableInterleaveIO :: IO a -> IO a
Documentation
unsafePrim :: MonadPrim s m => (State# s' -> (# State# s', a #)) -> m a Source #
Coerce the state token of prim operation and wrap it into a MonadPrim
action.
Highly unsafe!
Since: 0.3.0
unsafePrim_ :: MonadPrim s m => (State# s' -> State# s') -> m () Source #
Coerce the state token of prim operation and wrap it into a MonadPrim
action.
Highly unsafe!
Since: 0.3.0
unsafePrimBase :: MonadPrimBase s' m => m a -> State# s -> (# State# s, a #) Source #
Unwrap any MonadPrimBase
action while coercing the state token
Highly unsafe!
unsafePrimBase_ :: MonadPrimBase s' m => m () -> State# s -> State# s Source #
Unwrap any MonadPrimBase
action that does not return anything, while coercing the
state token
Highly unsafe!
unsafePrimBaseToPrim :: (MonadPrimBase sn n, MonadPrim sm m) => n a -> m a Source #
Convert a MonadPrimBase
action to another MonadPrim
while coercing the state token.
Highly unsafe!
unsafePrimBaseToIO :: MonadPrimBase s m => m a -> IO a Source #
Convert a MonadPrimBase
action to IO
while coercing the state token to RealWorld
.
Highly unsafe!
unsafePrimBaseToST :: MonadPrimBase sm m => m a -> ST s a Source #
Convert a MonadPrimBase
action to ST
while coercing the state token s
.
Highly unsafe!
unsafeIOToPrim :: MonadPrim s m => IO a -> m a Source #
Convert an IO
action to some MonadPrim
while coercing the state token.
Highly unsafe!
It is similar to unsafeSTToIO
, except resulting action can be
any other MonadPrim
action, therefore it is a lot more dangerous.
unsafeSTToPrim :: MonadPrim s' m => ST s a -> m a Source #
unsafeLiftPrimBase :: forall sn n sm m a. (MonadPrimBase sn n, MonadPrim sm m) => n a -> m a Source #
A version of liftPrimBase
that coerce the state token.
Highly unsafe!
noDuplicatePrim :: MonadPrim s m => m () Source #
Same as noDuplicate
, except works in any MonadPrim
.
unsafeDupablePerformPrimBase :: MonadPrimBase s m => m a -> a Source #
Same as unsafeDupablePerformIO
, except works not only with IO
, but with other
MonadPrimBase
actions as well. Reading and writing values into memory is safe, as
long as writing action is idempotent. On the other hand things like memory or resource
allocation, exceptions handling are not safe at all, since supplied action can be run
multiple times and a copy interrupted at will.
Inline
unsafeInlineIO :: IO a -> a Source #
Take an IO
and compute it as a pure value, while inlining the action itself.
Ridiculously unsafe!
This is even more unsafe then both unsafePerformIO
and unsafeDupableInterleaveIO
.
The only time it is really safe to use is on idempotent action that only read values from memory, but do note do any mutation, allocation and certainly not interaction with real world.
In
bytestring
it is known as accursedUnutterablePerformIO
. Here are some resources that discuss
it's unsafety:
unsafeInlineST :: ST s a -> a Source #
Take an ST
and compute it as a pure value, while inlining the action itself. Same
as unsafeInlineIO
.
Ridiculously unsafe!
unsafeInlinePrimBase :: MonadPrimBase s m => m a -> a Source #
Take any MonadPrimBase
action and compute it as a pure value, while inlining the
action. Same as unsafeInlineIO
, but applied to any MonadPrimBase
action.
Ridiculously unsafe!
Interleave
unsafeInterleavePrimBase :: MonadPrimBase s m => m a -> m a Source #
Same as unsafeInterleaveIO
, except works in any MonadPrimBase
unsafeDupableInterleavePrimBase :: MonadPrimBase s m => m a -> m a Source #
Same as unsafeDupableInterleaveIO
, except works in any MonadPrimBase
Re-exports
unsafePerformIO :: IO a -> a #
This is the "back door" into the IO
monad, allowing
IO
computation to be performed at any time. For
this to be safe, the IO
computation should be
free of side effects and independent of its environment.
If the I/O computation wrapped in unsafePerformIO
performs side
effects, then the relative order in which those side effects take
place (relative to the main I/O trunk, or other calls to
unsafePerformIO
) is indeterminate. Furthermore, when using
unsafePerformIO
to cause side-effects, you should take the following
precautions to ensure the side effects are performed as many times as
you expect them to be. Note that these precautions are necessary for
GHC, but may not be sufficient, and other compilers may require
different precautions:
- Use
{-# NOINLINE foo #-}
as a pragma on any functionfoo
that callsunsafePerformIO
. If the call is inlined, the I/O may be performed more than once. - Use the compiler flag
-fno-cse
to prevent common sub-expression elimination being performed on the module, which might combine two side effects that were meant to be separate. A good example is using multiple global variables (liketest
in the example below). - Make sure that the either you switch off let-floating (
-fno-full-laziness
), or that the call tounsafePerformIO
cannot float outside a lambda. For example, if you say:f x = unsafePerformIO (newIORef [])
you may get only one reference cell shared between all calls tof
. Better would bef x = unsafePerformIO (newIORef [x])
because now it can't float outside the lambda.
It is less well known that
unsafePerformIO
is not type safe. For example:
test :: IORef [a] test = unsafePerformIO $ newIORef [] main = do writeIORef test [42] bang <- readIORef test print (bang :: [Char])
This program will core dump. This problem with polymorphic references
is well known in the ML community, and does not arise with normal
monadic use of references. There is no easy way to make it impossible
once you use unsafePerformIO
. Indeed, it is
possible to write coerce :: a -> b
with the
help of unsafePerformIO
. So be careful!
unsafeDupablePerformIO :: IO a -> a #
This version of unsafePerformIO
is more efficient
because it omits the check that the IO is only being performed by a
single thread. Hence, when you use unsafeDupablePerformIO
,
there is a possibility that the IO action may be performed multiple
times (on a multiprocessor), and you should therefore ensure that
it gives the same results each time. It may even happen that one
of the duplicated IO actions is only run partially, and then interrupted
in the middle without an exception being raised. Therefore, functions
like bracket
cannot be used safely within
unsafeDupablePerformIO
.
Since: base-4.4.0.0
unsafeInterleaveIO :: IO a -> IO a #
unsafeInterleaveIO
allows an IO
computation to be deferred lazily.
When passed a value of type IO a
, the IO
will only be performed
when the value of the a
is demanded. This is used to implement lazy
file reading, see hGetContents
.
unsafeDupableInterleaveIO :: IO a -> IO a #
unsafeDupableInterleaveIO
allows an IO
computation to be deferred lazily.
When passed a value of type IO a
, the IO
will only be performed
when the value of the a
is demanded.
The computation may be performed multiple times by different threads,
possibly at the same time. To ensure that the computation is performed
only once, use unsafeInterleaveIO
instead.