With careful application of typeclass instances to this GADT, and by
redefining 'ConcT' in terms of it, this solves the type inference
problem and removes the need for the 'basic' function. This approach
also has less newtype wrapping/unwrapping, and so is probably a step
in the right direction even without the type inference advantages.
The diff is quite big because things have needed to migrate between
modules to avoid the import graph getting even worse.
The 'Program' is the new formulation of dejafu unit tests. A
'Program' is one of three types:
- A 'ConcT', which is as before.
- A 'WithSetup', which corresponds to 'dontCheck'.
- A 'WithSetupAndTeardown', which corresponds to 'subconcurrency'.
This more new formulation makes it impossible to nest 'withSetup' (the
replacement for 'dontCheck') or 'withSetupAndTeardown' (the
half-replacement for 'subconcurrency'), by as these functions take a
'ConcT' as their argument and produce a 'Program WithSetup' or
'Program WithSetupAndTeardown'.
The testing functions have all been generalised to work with this
'Program' type.
1. Discard function (if present)
2. Way (if present)
3. Memory type (if present)
4. Name of test
5. Predicate
6. Action
For multi-predicate functions, 4 and 5 are replaced with a list.
Also adds a Functor and Profunctor instance for predicates. The old
predicate type is kept as an alias for the (common) case where both
tyvars are the same.
This also adds forkOS(N) and isCurrentThreadBound to MonadConc, a
breaking change.
Note: forkOSWithUnmask(N) is NOT added to MonadConc, as it isn't
supported in base-4.8 (GHC 7.10). See #132 for the action on this.
A bound thread under test gets a dedicated worker thread, which is
forked bound using the underlying MonadConc. This worker is used for
all lifted actions, with execution as normal otherwise.
This is preparation for adding bound threads. The instance isn't used
in this commit, but the diff is large enough that I feel this should
be a separate commit for ease of review.
Fallout:
- The MonadBaseControl IO instance is gone, as I'm not sure how to do
it generally.
- The pure/IO split is gone, everything is now monadic.
- The execution, SCT, and dejafu functions are of the form (MonadConc
n, MonadRef r n) => ...