lvish-2.0: Parallel scheduler, LVar data structures, and infrastructure to build more.

Safe HaskellUnsafe




This is not a datatype for the end-user.

Rather, this module is for building new LVar types in a comparatively easy way: by putting a pure value in a mutable container, and defining a put operation as a pure function.

The data structure implementor who uses this module must guarantee that their put operation computes a least upper bound, ensuring that the set of states that their LVar type can take on form a join-semilattice (



newtype PureLVar s t

An LVar which consists merely of an immutable, pure value inside a mutable box.


PureLVar (LVar s (IORef t) t) 


Eq (PureLVar s v)

Physical identity, just as with IORefs.

Show a => Show (PureLVar Frzn a) 
DeepFrz a => DeepFrz (PureLVar s a) 

newPureLVar :: JoinSemiLattice t => t -> Par e s (PureLVar s t)

A new pure LVar populated with the provided initial state.

putPureLVar :: (JoinSemiLattice t, HasPut e) => PureLVar s t -> t -> Par e s ()

Put a new value which will be joined with the old.

waitPureLVar :: (JoinSemiLattice t, Eq t, HasGet e) => PureLVar s t -> t -> Par e s ()

Wait until the pure LVar has crossed a threshold and then unblock. (In the semantics, this is a singleton query set.)

freezePureLVar :: HasFreeze e => PureLVar s t -> Par e s t

Freeze the pure LVar, returning its exact value. Subsequent puts will raise an error.

getPureLVar :: (JoinSemiLattice t, Eq t, HasGet e) => PureLVar s t -> [t] -> Par e s t

Blocks until the contents of lv are at or above one element of thrshSet, then returns that one element.

getPureLVarSets :: (JoinSemiLattice t, Eq t, Ord t, HasGet e) => PureLVar s t -> [(b, Set t)] -> Par e s (b, Set t)

A variant of getPureLVar that allows equivalence classes of sets. All equivalence classes in a threshold set must still be pairwise incompatible.

Further, as a result of running this get, you find out only which equivalence class the current state is at or above, not exactly which state within that equivalence class.

Finally, to make it easy to know WHICH set you got back, we allow each set to be tagged with an arbitrary additional value. For example, it may be useful to use a unique Int for this purpose.

unsafeGetPureLVar :: (JoinSemiLattice t, Eq t, HasGet e) => PureLVar s t -> (t -> Bool) -> Par e s t

Like getPureLVar but uses a threshold function rather than an explicit set.

Verifying lattice structure

verifyFiniteJoin :: (Eq a, Show a) => [a] -> (a -> a -> a) -> Maybe String

Takes a finite set of states and a join operation (e.g., for an instance of JoinSemiLattice) and returns an error message if the join-semilattice properties don't hold.

verifyFiniteGet :: (Eq a, Show a, JoinSemiLattice a, Eq b, Show b) => [a] -> (b, b) -> (a -> b) -> Maybe String

Verify that a blocking get is monotone in just the right way. This takes a designated bottom and top element.