Safe Haskell | None |
---|---|
Language | Haskell2010 |
The implementation of the Haxl
monad. Most users should
import Haxl.Core instead of importing this module directly.
Synopsis
- newtype GenHaxl u w a = GenHaxl {}
- data Result u w a
- data WriteTree w
- = NilWrites
- | SomeWrite w
- | MergeWrites (WriteTree w) (WriteTree w)
- tellWrite :: w -> GenHaxl u w ()
- write :: WriteTree w -> GenHaxl u w ()
- flattenWT :: WriteTree w -> [w]
- appendWTs :: WriteTree w -> WriteTree w -> WriteTree w
- mbModifyWLRef :: WriteTree w -> IORef (WriteTree w) -> IO ()
- data Cont u w a
- toHaxl :: Cont u w a -> GenHaxl u w a
- newtype IVar u w a = IVar (IORef (IVarContents u w a))
- data IVarContents u w a
- newIVar :: IO (IVar u w a)
- newFullIVar :: ResultVal a w -> IO (IVar u w a)
- getIVar :: IVar u w a -> GenHaxl u w a
- getIVarWithWrites :: IVar u w a -> GenHaxl u w a
- putIVar :: IVar u w a -> ResultVal a w -> Env u w -> IO ()
- data ResultVal a w
- = Ok a (WriteTree w)
- | ThrowHaxl SomeException (WriteTree w)
- | ThrowIO SomeException
- done :: ResultVal a w -> IO (Result u w a)
- eitherToResult :: Either SomeException a -> ResultVal a w
- eitherToResultThrowIO :: Either SomeException a -> ResultVal a w
- data CompleteReq u w = CompleteReq (Either SomeException a) !(IVar u w a) !Int64
- data Env u w = Env {
- cacheRef :: !(IORef (DataCache (IVar u w)))
- memoRef :: !(IORef (DataCache (IVar u w)))
- flags :: !Flags
- userEnv :: u
- statsRef :: !(IORef Stats)
- profLabel :: ProfileLabel
- profRef :: !(IORef Profile)
- states :: StateStore
- reqStoreRef :: !(IORef (RequestStore u))
- runQueueRef :: !(IORef (JobList u w))
- submittedReqsRef :: !(IORef ReqCountMap)
- completions :: !(TVar [CompleteReq u w])
- pendingWaits :: [IO ()]
- speculative :: !Int
- writeLogsRef :: !(IORef (WriteTree w))
- type Caches u w = (IORef (DataCache (IVar u w)), IORef (DataCache (IVar u w)))
- caches :: Env u w -> Caches u w
- initEnvWithData :: StateStore -> u -> Caches u w -> IO (Env u w)
- initEnv :: StateStore -> u -> IO (Env u w)
- emptyEnv :: u -> IO (Env u w)
- env :: (Env u w -> a) -> GenHaxl u w a
- withEnv :: Env u w -> GenHaxl u w a -> GenHaxl u w a
- speculate :: Env u w -> Env u w
- imperative :: Env u w -> Env u w
- data JobList u w
- appendJobList :: JobList u w -> JobList u w -> JobList u w
- lengthJobList :: JobList u w -> Int
- addJob :: Env u w -> GenHaxl u w b -> IVar u w b -> IVar u w a -> IO ()
- throw :: Exception e => e -> GenHaxl u w a
- raise :: Exception e => e -> IO (Result u w a)
- catch :: Exception e => GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
- catchIf :: Exception e => (e -> Bool) -> GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a
- try :: Exception e => GenHaxl u w a -> GenHaxl u w (Either e a)
- tryToHaxlException :: GenHaxl u w a -> GenHaxl u w (Either HaxlException a)
- dumpCacheAsHaskell :: GenHaxl u w String
- dumpCacheAsHaskellFn :: String -> String -> GenHaxl u w String
- unsafeLiftIO :: IO a -> GenHaxl u w a
- unsafeToHaxlException :: GenHaxl u w a -> GenHaxl u w a
The monad
newtype GenHaxl u w a Source #
The Haxl monad, which does several things:
- It is a reader monad for
Env
, which contains the current state of the scheduler, including unfetched requests and the run queue of computations. - It is a writer monad for
WriteTree
. We strongly advise these be used only for logs used for debugging. These are not memoized. Other relevant writes should be returned as function output, which is the more "functional" way.
Instances
Monad (GenHaxl u w) Source # | |
Functor (GenHaxl u w) Source # | |
Applicative (GenHaxl u w) Source # | |
Defined in Haxl.Core.Monad | |
MonadThrow (GenHaxl u w) Source # | Since: 0.3.1.0 |
Defined in Haxl.Core.Monad | |
MonadCatch (GenHaxl u w) Source # | Since: 0.3.1.0 |
Fractional a => Fractional (GenHaxl u w a) Source # | |
Num a => Num (GenHaxl u w a) Source # | |
Defined in Haxl.Prelude (+) :: GenHaxl u w a -> GenHaxl u w a -> GenHaxl u w a # (-) :: GenHaxl u w a -> GenHaxl u w a -> GenHaxl u w a # (*) :: GenHaxl u w a -> GenHaxl u w a -> GenHaxl u w a # negate :: GenHaxl u w a -> GenHaxl u w a # abs :: GenHaxl u w a -> GenHaxl u w a # signum :: GenHaxl u w a -> GenHaxl u w a # fromInteger :: Integer -> GenHaxl u w a # | |
IsString a => IsString (GenHaxl u w a) Source # | |
Defined in Haxl.Core.Monad fromString :: String -> GenHaxl u w a # | |
u1 ~ u2 => IfThenElse (GenHaxl u1 w Bool) (GenHaxl u2 w a) Source # | |
Defined in Haxl.Prelude |
The result of a computation is either Done
with a value, Throw
with an exception, or Blocked
on the result of a data fetch with
a continuation.
Writes (for debugging only)
A tree of writes done during a Haxl computation. We could use a simple list, but this allows us to avoid multiple mappends when concatenating writes from two haxl computations.
Users should try to treat this data type as opaque, and prefer
to use flattenWT
to get a simple list of writes from a WriteTree
.
NilWrites | |
SomeWrite w | |
MergeWrites (WriteTree w) (WriteTree w) |
Cont
A data representation of a Haxl continuation. This is to avoid repeatedly traversing a left-biased tree in a continuation, leading O(n^2) complexity for some pathalogical cases - see the "seql" benchmark in tests/MonadBench.hs. See "A Smart View on Datatypes", Jaskelioff/Rivas, ICFP'15
IVar
A synchronisation point. It either contains a value, or a list of computations waiting for the value.
IVar (IORef (IVarContents u w a)) |
getIVarWithWrites :: IVar u w a -> GenHaxl u w a Source #
ResultVal
The contents of a full IVar. We have to distinguish exceptions thrown in the IO monad from exceptions thrown in the Haxl monad, so that when the result is fetched using getIVar, we can throw the exception in the right way.
Ok a (WriteTree w) | |
ThrowHaxl SomeException (WriteTree w) | |
ThrowIO SomeException |
eitherToResult :: Either SomeException a -> ResultVal a w Source #
eitherToResultThrowIO :: Either SomeException a -> ResultVal a w Source #
CompleteReq
data CompleteReq u w Source #
A completed request from a data source, containing the result,
and the IVar
representing the blocked computations. The job of a
data source is just to add these to a queue (completions
) using
putResult
; the scheduler collects them from the queue and unblocks
the relevant computations.
CompleteReq (Either SomeException a) !(IVar u w a) !Int64 |
Env
The data we carry around in the Haxl monad.
Env | |
|
initEnvWithData :: StateStore -> u -> Caches u w -> IO (Env u w) Source #
Initialize an environment with a StateStore
, an input map, a
preexisting DataCache
, and a seed for the random number generator.
initEnv :: StateStore -> u -> IO (Env u w) Source #
Initializes an environment with StateStore
and an input map.
withEnv :: Env u w -> GenHaxl u w a -> GenHaxl u w a Source #
Returns a version of the Haxl computation which always uses the
provided Env
, ignoring the one specified by runHaxl
.
imperative :: Env u w -> Env u w Source #
JobList
A list of computations together with the IVar into which they should put their result.
This could be an ordinary list, but the optimised representation saves space and time.
lengthJobList :: JobList u w -> Int Source #
Exceptions
catch :: Exception e => GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a Source #
Catch an exception in the Haxl monad
catchIf :: Exception e => (e -> Bool) -> GenHaxl u w a -> (e -> GenHaxl u w a) -> GenHaxl u w a Source #
Catch exceptions that satisfy a predicate
tryToHaxlException :: GenHaxl u w a -> GenHaxl u w (Either HaxlException a) Source #
Like try
, but lifts all exceptions into the HaxlException
hierarchy. Uses unsafeToHaxlException
internally. Typically
this is used at the top level of a Haxl computation, to ensure that
all exceptions are caught.
Dumping the cache
dumpCacheAsHaskell :: GenHaxl u w String Source #
Dump the contents of the cache as Haskell code that, when compiled and run, will recreate the same cache contents. For example, the generated code looks something like this:
loadCache :: GenHaxl u w () loadCache = do cacheRequest (ListWombats 3) (Right ([1,2,3])) cacheRequest (CountAardvarks "abcabc") (Right (2))
dumpCacheAsHaskellFn :: String -> String -> GenHaxl u w String Source #
Dump the contents of the cache as Haskell code that, when compiled and run, will recreate the same cache contents. Does not take into account the writes done as part of the computation.
Takes the name and type for the resulting function as arguments.
CallGraph
Unsafe operations
unsafeLiftIO :: IO a -> GenHaxl u w a Source #
Under ordinary circumstances this is unnecessary; users of the Haxl monad should generally not perform arbitrary IO.
unsafeToHaxlException :: GenHaxl u w a -> GenHaxl u w a Source #
Convert exceptions in the underlying IO monad to exceptions in the Haxl monad. This is morally unsafe, because you could then catch those exceptions in Haxl and observe the underlying execution order. Not to be exposed to user code.