Safe Haskell | Trustworthy |
---|
The DeepFrz
module provides a way to return arbitrarily complex data
structures containing LVars from Par
computations.
The important thing to know is that to use runParThenFreeze
to run a
Par
computation, you must make sure that all types you return from
the Par
computation have DeepFrz
instances. This means that, if
you wish to return a user-defined type, you will need to include a bit
of boilerplate to give it a DeepFrz
instance. Here is a complete
example:
import Control.LVish.DeepFrz data MyData = MyData Int deriving Show instance DeepFrz MyData where type FrzType MyData = MyData main = print (runParThenFreeze (return (MyData 3)))
The functions you'll want to use
runParThenFreeze :: DeepFrz a => Par Det NonFrzn a -> FrzType aSource
Under normal conditions, calling a freeze
operation inside a
Par
computation makes the Par
computation quasi-deterministic.
However, if we freeze only after all LVar operations are completed
(after the implicit global barrier of runPar
), then we've avoided
all data races, and freezing is therefore safe. Running a Par
computation with runParThenFreeze
accomplishes this, without our
having to call freeze
explicitly.
In order to use runParThenFreeze
, the type returned from the
Par
computation must be a member of the DeepFrz
class. All the
Data.LVar.*
libraries should provide instances of DeepFrz
already. Further, you can create additional instances for custom,
pure datatypes. The result of a runParThenFreeze
depends on the
type-level function FrzType
, whose only purpose is to toggle the
s
parameters of all IVars to the Frzn
state.
Significantly, the freeze at the end of runParThenFreeze
has no runtime cost, in
spite of the fact that it enables a deep (recursive) freeze of the value returned
by the Par
computation.
runParThenFreezeIO :: DeepFrz a => Par d NonFrzn a -> IO (FrzType a)Source
This version works for nondeterministic computations as well.
Of course, nondeterministic computations may also call freeze
internally, but this function has an advantage to doing your own
freeze
at the end of a runParIO
: there is an implicit barrier
before the final freeze. Further, DeepFrz
has no runtime
overhead, whereas regular freezing has a cost.
Some supporting types
DeepFreezing is a type-level (guaranteed O(1) time complexity)
operation. It marks an LVar and its contents (recursively) as
frozen. DeepFreezing is not an action that can be taken directly
by the user, however. Rather, it is the final step in a
runParThenFreeze
invocation.
This type function is public. It maps pre-frozen types to frozen ones. It should be idempotent.
This exists only for the purpose of being a type which is not equal to Frzn
.
One could just as well have used ()
, but this is more descriptive.
An uninhabited type that signals that an LVar has been frozen.
LVars should use this in place of their s
parameter.
Foldable (IStructure Frzn) | |
Foldable (ISet Frzn) | |
Foldable (ISet Frzn) | |
Show a => Show (IVar Frzn a) | |
Show a => Show (IStructure Frzn a) | |
Show a => Show (ISet Frzn a) | |
Show a => Show (ISet Frzn a) | |
Show a => Show (PureLVar Frzn a) | |
Foldable (IMap k Frzn) | |
Foldable (IMap k Frzn) | |
(Show k, Show a) => Show (IMap k Frzn a) | |
(Show k, Show a) => Show (IMap k Frzn a) |
An uninhabited type that signals that an LVar is not only frozen, but it may be traversed in whatever order its internal representation dictates.
Foldable (IVar Trvrsbl) | |
Foldable (IStructure Trvrsbl) | |
Foldable (ISet Trvrsbl) | |
Foldable (ISet Trvrsbl) | |
Show a => Show (IVar Trvrsbl a) | For convenience only; the user could define this. |
Show a => Show (IStructure Trvrsbl a) | For convenience only; the user could define this. |
Show a => Show (ISet Trvrsbl a) | For convenience; the user could define this. |
Show a => Show (ISet Trvrsbl a) | For convenience only; the user could define this. |
Foldable (IMap k Trvrsbl) | |
Foldable (IMap k Trvrsbl) | |
(Show k, Show a) => Show (IMap k Trvrsbl a) | For convenience only; the user could define this. |
(Show k, Show a) => Show (IMap k Trvrsbl a) | For convenience only; the user could define this. |