Safe Haskell | Safe |
---|---|
Language | GHC2021 |
LambdaUC.Syntax.Async.Eval
Synopsis
- data Exec ach (i :: InitStatus) where
- ExecProc :: InitStatusIndexRetD st i res -> AsyncT ach i i res -> Exec ach st
- ExecSpawnOnDemand :: forall l r ports. ConstrAllD Ord l -> ConstrAllD Ord r -> KnownHPPortsD ports -> KnownLenD l -> KnownLenD r -> (HListPair l r -> Exec ports InitAbsent) -> Exec (MapConcat2 l r ports) InitAbsent
- ExecFork :: InitStatusCompD st st' -> KnownLenD ach -> Exec ach st -> Exec ach' st' -> Exec (Concat ach ach') (InitStatusOr st st')
- ExecSwap :: ListSplitD l p (f : l') -> ListSplitD l' p' (s : rest) -> Exec l st -> Exec (Concat p (s : Concat p' (f : rest))) st
- ExecLink :: ListSplitD l p ((x :> y) : l') -> ListSplitD l' p' ((y :> x) : rest) -> Exec l st -> Exec (Concat p (Concat p' rest)) st
- runExec :: Exec '[] (InitPresent a) -> PrAlgo a
- runExecAsync :: Exec ach st -> AsyncT ach (InitStatusIndex st) (InitStatusIndex st) (InitStatusRes st)
- newtype ExecBuilder i j a = ExecBuilder {
- fromExecBuilder :: XAccum (MatchExecIndex i) (MatchExecIndex j) a
- data ExecIndex
- runExecBuilder :: ExecBuilder ExecIndexInit (ExecIndexSome l st) () -> MatchExecIndex (ExecIndexSome l st)
- process :: InitStatusIndexRet st i res => AsyncT l i i res -> ExecBuilder ExecIndexInit (ExecIndexSome l st) ()
- forkLeft :: (InitStatusComp st st', KnownLen l) => ExecBuilder ExecIndexInit (ExecIndexSome l' st') () -> ExecBuilder (ExecIndexSome l st) (ExecIndexSome (Concat l l') (InitStatusOr st st')) ()
- forkRight :: (InitStatusComp st st', KnownLen l) => ExecBuilder ExecIndexInit (ExecIndexSome l st) () -> ExecBuilder (ExecIndexSome l' st') (ExecIndexSome (Concat l l') (InitStatusOr st st')) ()
- link :: ListSplitD l p ((x :> y) : l') -> ListSplitD l' p' ((y :> x) : rest) -> ExecBuilder (ExecIndexSome l st) (ExecIndexSome (Concat p (Concat p' rest)) st) ()
- swap :: ListSplitD l p (f : l') -> ListSplitD l' p' (s : rest) -> ExecBuilder (ExecIndexSome l st) (ExecIndexSome (Concat p (s : Concat p' (f : rest))) st) ()
- spawnOnDemand :: (ConstrAll Ord l, ConstrAll Ord r, KnownHPPorts ports, KnownLen l, KnownLen r) => (HListPair l r -> ExecBuilder ExecIndexInit (ExecIndexSome ports InitAbsent) ()) -> ExecBuilder ExecIndexInit (ExecIndexSome (MapConcat2 l r ports) InitAbsent) ()
- execGuard :: forall l st. ExecBuilder (ExecIndexSome l st) (ExecIndexSome l st) ()
- execInvariantM :: ExecBuilder (ExecIndexSome ach st) (ExecIndexSome ach st) (SomeInitStatusIndexRetD st)
- process' :: InitStatusIndexRetD st i res -> AsyncT l i i res -> ExecBuilder ExecIndexInit (ExecIndexSome l st) ()
- forkLeft' :: InitStatusCompD st st' -> KnownLenD l -> ExecBuilder ExecIndexInit (ExecIndexSome l' st') () -> ExecBuilder (ExecIndexSome l st) (ExecIndexSome (Concat l l') (InitStatusOr st st')) ()
- forkRight' :: InitStatusCompD st st' -> KnownLenD l -> ExecBuilder ExecIndexInit (ExecIndexSome l st) () -> ExecBuilder (ExecIndexSome l' st') (ExecIndexSome (Concat l l') (InitStatusOr st st')) ()
- spawnOnDemand' :: forall l r ports. ConstrAllD Ord l -> ConstrAllD Ord r -> KnownHPPortsD ports -> KnownLenD l -> KnownLenD r -> (HListPair l r -> ExecBuilder ExecIndexInit (ExecIndexSome ports InitAbsent) ()) -> ExecBuilder ExecIndexInit (ExecIndexSome (MapConcat2 l r ports) InitAbsent) ()
- getForkIndexSwap :: ForkIndexCompD i i' -> ForkIndexCompD i' i
- data InitStatus
- data InitStatusIndexRetD (s :: InitStatus) (i :: Index) (res :: Type) where
Execution Syntax
This section defines syntax for distributed exection of processes.
You define your processes and their links as a value of type Exec
,
and then run it using runExec
.
You start with the processes defined as
wrapped
in AsyncT
m ach i i a`ExecProc
, then you combine them using ExecFork
, ExecLink
and
ExecSwap
until you've linked all the free ports and left with
. The latter can be evaluated with Exec
m '[] NextSend
arunExec
to
yield the final result of evaluation.
Only one process in the whole execution is allowed to return a result. It
is the (only) process that finishes in NextSend
state, all the other
processes are forced to have their return type Void
(and never
finish). These conditions are checked statically by the typeclass
restrictions of Exec
constructors.
Function runExec
returns the result of the process that termiates in
NextSend
.
data Exec ach (i :: InitStatus) where #
Constructors
ExecProc | An execution consisting of one process. |
Fields
| |
ExecSpawnOnDemand :: forall l r ports. ConstrAllD Ord l -> ConstrAllD Ord r -> KnownHPPortsD ports -> KnownLenD l -> KnownLenD r -> (HListPair l r -> Exec ports InitAbsent) -> Exec (MapConcat2 l r ports) InitAbsent | |
ExecFork | Combine two executions. |
Fields
| |
ExecSwap | Swap positions of two adjacent free ports. |
Fields
| |
ExecLink | Link two adjacent free ports of a given execution (making them bound). |
Fields
|
runExec :: Exec '[] (InitPresent a) -> PrAlgo a #
Run an execution.
Note that the list of free ports must be empty, i.e. all ports must be bound for an execution to be defined.
runExecAsync :: Exec ach st -> AsyncT ach (InitStatusIndex st) (InitStatusIndex st) (InitStatusRes st) #
Monad for Building Executions
This section defines the ExecBuilder
monad that simplifies the construction
of Exec
exections. Any Exec
value is built like a tree where each node
is marked with one of constructors of Exec
: ExecFork
has two children
nodes, ExecProc
is a leaf (no children nodes), while ExecSwap
and
ExecFork
have one child each.
This structure, while precisely matching the technical aspect of
constructing an execution, are not so convenient for human to
build. Especially, if your Exec
formala is complex and you want to build
it gradually and see intermediate results.
The ExecBuilder
monad aids in building Exec
values in a modular
way and providing the programmer with feedback at each step. Each
ExecBuilder
action internally stores a function
or a function Exec
l m i res ->
Exec
l' m i' res'() ->
(given by the
Exec
l m i resExecIndex
). Two actions can be composed together if the corresponding
functions compose.
To get a runnable execution
, define a value of type
Exec
'[] m i res
and pass it
to ExecBuilder
m ExecIndexInit
(ExecIndexSome
l i res) ()runExecBuilder
. The result can be passed to runExec
to actually
run it. The basic actions available in ExecBuilder
are forkLeft
,
forkRight
, link
and swap
.
newtype ExecBuilder i j a #
Constructors
ExecBuilder | |
Fields
|
Instances
XApplicative ExecBuilder # | |
Defined in LambdaUC.Syntax.Async.Eval Methods xpure :: forall a (p :: k). a -> ExecBuilder p p a # (<*>:) :: forall (p :: k) (q :: k) a b (r :: k). ExecBuilder p q (a -> b) -> ExecBuilder q r a -> ExecBuilder p r b # xliftA2 :: forall a b c (p :: k) (q :: k) (r :: k). (a -> b -> c) -> ExecBuilder p q a -> ExecBuilder q r b -> ExecBuilder p r c # (*>:) :: forall (p :: k) (q :: k) a (r :: k) b. ExecBuilder p q a -> ExecBuilder q r b -> ExecBuilder p r b # (<*:) :: forall (p :: k) (q :: k) a (r :: k) b. ExecBuilder p q a -> ExecBuilder q r b -> ExecBuilder p r a # | |
XMonad ExecBuilder # | |
Defined in LambdaUC.Syntax.Async.Eval Methods (>>=:) :: forall a b (p :: k) (q :: k) (r :: k). ExecBuilder p q a -> (a -> ExecBuilder q r b) -> ExecBuilder p r b # (>>:) :: forall a b (p :: k) (q :: k) (r :: k). ExecBuilder p q a -> ExecBuilder q r b -> ExecBuilder p r b # xreturn :: forall a (p :: k). a -> ExecBuilder p p a # | |
Functor (ExecBuilder i j) # | |
Defined in LambdaUC.Syntax.Async.Eval Methods fmap :: (a -> b) -> ExecBuilder i j a -> ExecBuilder i j b # (<$) :: a -> ExecBuilder i j b -> ExecBuilder i j a # |
Index of the ExecBuilder
monad.
Constructors
ExecIndexInit | We haven't started any executions |
ExecIndexSome [Port] InitStatus | An execution with given |
Instances
XApplicative ExecBuilder # | |
Defined in LambdaUC.Syntax.Async.Eval Methods xpure :: forall a (p :: k). a -> ExecBuilder p p a # (<*>:) :: forall (p :: k) (q :: k) a b (r :: k). ExecBuilder p q (a -> b) -> ExecBuilder q r a -> ExecBuilder p r b # xliftA2 :: forall a b c (p :: k) (q :: k) (r :: k). (a -> b -> c) -> ExecBuilder p q a -> ExecBuilder q r b -> ExecBuilder p r c # (*>:) :: forall (p :: k) (q :: k) a (r :: k) b. ExecBuilder p q a -> ExecBuilder q r b -> ExecBuilder p r b # (<*:) :: forall (p :: k) (q :: k) a (r :: k) b. ExecBuilder p q a -> ExecBuilder q r b -> ExecBuilder p r a # | |
XMonad ExecBuilder # | |
Defined in LambdaUC.Syntax.Async.Eval Methods (>>=:) :: forall a b (p :: k) (q :: k) (r :: k). ExecBuilder p q a -> (a -> ExecBuilder q r b) -> ExecBuilder p r b # (>>:) :: forall a b (p :: k) (q :: k) (r :: k). ExecBuilder p q a -> ExecBuilder q r b -> ExecBuilder p r b # xreturn :: forall a (p :: k). a -> ExecBuilder p p a # |
runExecBuilder :: ExecBuilder ExecIndexInit (ExecIndexSome l st) () -> MatchExecIndex (ExecIndexSome l st) #
Extract the internal Exec
from ExecBuilder
.
Note that `ExecBuilder m i j ()` internally stores a function
. The function can be extracted
using MatchExecIndex
i -> MatchExecIndex
jrunXWriter
.
At the same time,
. Therefore,
MatchExecIndex
ExecIndexInit
= ()`
stores a function
ExecBuilder
m ExecIndexInit
(ExecIndexSome
l i res)() ->
, which is isomorphic to just value Exec
m l i res
, which this functions extracts.Exec
m l i
res
Actions
The following are basic actions you can perform in ExecBuilder
. The
process
, forkLeft
, forkRight
, link
, swap
correpond to the
constructors of Exec
. The difference between forkLeft
and forkRight
is
merely in the order of composing the child nodes.
The
has no effect in the monad, but can be inserted
in-between other operations in execGuard
= xreturn ()ExecBuilder
to annotate the current
context. This can be used to document the code, while having the compiler
verify that the annotation is correct. In some rare cases, execGuard
can also
be used to resolve ambiguous types.
Arguments
:: InitStatusIndexRet st i res | |
=> AsyncT l i i res | The program that the created process will run |
-> ExecBuilder ExecIndexInit (ExecIndexSome l st) () |
Arguments
:: (InitStatusComp st st', KnownLen l) | |
=> ExecBuilder ExecIndexInit (ExecIndexSome l' st') () | Right branch of the fork |
-> ExecBuilder (ExecIndexSome l st) (ExecIndexSome (Concat l l') (InitStatusOr st st')) () |
Arguments
:: (InitStatusComp st st', KnownLen l) | |
=> ExecBuilder ExecIndexInit (ExecIndexSome l st) () | Left branch of the fork |
-> ExecBuilder (ExecIndexSome l' st') (ExecIndexSome (Concat l l') (InitStatusOr st st')) () |
Arguments
:: ListSplitD l p ((x :> y) : l') | Proof of |
-> ListSplitD l' p' ((y :> x) : rest) | Proof of |
-> ExecBuilder (ExecIndexSome l st) (ExecIndexSome (Concat p (Concat p' rest)) st) () |
Arguments
:: ListSplitD l p (f : l') | Proof of |
-> ListSplitD l' p' (s : rest) | Proof of |
-> ExecBuilder (ExecIndexSome l st) (ExecIndexSome (Concat p (s : Concat p' (f : rest))) st) () |
spawnOnDemand :: (ConstrAll Ord l, ConstrAll Ord r, KnownHPPorts ports, KnownLen l, KnownLen r) => (HListPair l r -> ExecBuilder ExecIndexInit (ExecIndexSome ports InitAbsent) ()) -> ExecBuilder ExecIndexInit (ExecIndexSome (MapConcat2 l r ports) InitAbsent) () #
execGuard :: forall l st. ExecBuilder (ExecIndexSome l st) (ExecIndexSome l st) () #
execInvariantM :: ExecBuilder (ExecIndexSome ach st) (ExecIndexSome ach st) (SomeInitStatusIndexRetD st) #
Following are the versions of process
, forkLeft
and forkRight
that
take the proofs as explicit arguments instead of implicit typeclass
constraints.
Arguments
:: InitStatusIndexRetD st i res | |
-> AsyncT l i i res | The program that the created process will run |
-> ExecBuilder ExecIndexInit (ExecIndexSome l st) () |
Arguments
:: InitStatusCompD st st' | Proof of |
-> KnownLenD l | Length of list |
-> ExecBuilder ExecIndexInit (ExecIndexSome l' st') () | Right branch of the fork |
-> ExecBuilder (ExecIndexSome l st) (ExecIndexSome (Concat l l') (InitStatusOr st st')) () |
Arguments
:: InitStatusCompD st st' | Proof of |
-> KnownLenD l | Length of list |
-> ExecBuilder ExecIndexInit (ExecIndexSome l st) () | Left branch of the fork |
-> ExecBuilder (ExecIndexSome l' st') (ExecIndexSome (Concat l l') (InitStatusOr st st')) () |
spawnOnDemand' :: forall l r ports. ConstrAllD Ord l -> ConstrAllD Ord r -> KnownHPPortsD ports -> KnownLenD l -> KnownLenD r -> (HListPair l r -> ExecBuilder ExecIndexInit (ExecIndexSome ports InitAbsent) ()) -> ExecBuilder ExecIndexInit (ExecIndexSome (MapConcat2 l r ports) InitAbsent) () #
Helper functions
getForkIndexSwap :: ForkIndexCompD i i' -> ForkIndexCompD i' i #
data InitStatus #
Constructors
InitAbsent | |
InitPresent Type |
data InitStatusIndexRetD (s :: InitStatus) (i :: Index) (res :: Type) where #
Constructors
InitStatusIndexRetAbsent :: InitStatusIndexRetD InitAbsent NextRecv Void | |
InitStatusIndexRetPresent :: InitStatusIndexRetD (InitPresent res) NextSend res |