0 | module Control.Cont.Thread
4 | import Control.HigherOrder
6 | import Control.Monad.Free
9 | data Thread : (Type -> Type) -> (Type -> Type) where
10 | Yield : m a -> Thread m a
11 | Fork : forall t. m t -> m a -> Thread m a
14 | HThread : (Type -> Type) -> (Type -> Type)
18 | yield : Inj Thread sig => Free sig ()
19 | yield = inject $
Yield $
return ()
22 | fork : Inj Thread sig => Free sig a -> Free sig ()
23 | fork d = inject $
Fork d $
return ()
26 | HFunctor Thread where
27 | hmap f (Yield x) = Yield (f x)
28 | hmap f (Fork x y) = Fork (f x) (f y)
32 | emap f (Yield p) = Yield (f p)
33 | emap f (Fork d p) = Fork d (f p)
35 | weave s hdl (Yield p) = Yield (hdl (map (const p) s))
36 | weave s hdl (Fork d p) = Fork (hdl (map (const d) s))
37 | (hdl (map (const p) s))
40 | data Daemon : ((Type -> Type) -> (Type -> Type)) -> Type where
41 | MkDaemon : forall t. Free (Thread :+: sig) t -> Daemon sig
44 | data SThread : (f : (Type -> Type) -> (Type -> Type))
47 | SYield : Free (Thread :+: sig) r -> SThread sig r
48 | SFork : Daemon sig -> Free (Thread :+: sig) r -> SThread sig r
49 | SActive : r -> SThread sig r
52 | Syntax sig => Functor (SThread sig) where
53 | map f (SActive x) = SActive (f x)
54 | map f (SYield p) = SYield (map f p)
55 | map f (SFork d p) = SFork d (map f p)
60 | => Handler (SThread sig) (Free (Thread :+: sig)) (Free sig)
61 | thread (SActive p) = runThread p
62 | thread (SYield p) = return (SYield (join p))
63 | thread (SFork d p) = return (SFork d (join p))
66 | runThread : Syntax sig
67 | => Free (Thread :+: sig) a -> Free sig (SThread sig a)
68 | runThread (Return x) = return (SActive x)
69 | runThread (Op (Inl (Yield q))) = return (SYield q)
70 | runThread (Op (Inl (Fork d q))) = return (SFork (MkDaemon d) q)
71 | runThread (Op (Inr op)) = Op (weave {s = SThread sig} (SActive ()) thread op)
74 | schedule : Syntax sig => Free (Thread :+: sig) a -> Free sig a
75 | schedule p = master p [] where
77 | daemons : List (Daemon sig) -> List (Daemon sig) -> Free (Thread :+: sig) a -> Free sig a
78 | daemons [] ds' p = master p (reverse ds')
79 | daemons (MkDaemon q :: ds) ds' p = do
82 | SActive _ => daemons ds ds' p
83 | SYield q' => daemons ds (MkDaemon q' :: ds') p
84 | SFork d' q' => daemons (d' :: ds) (MkDaemon q' :: ds') p
86 | master : Free (Thread :+: sig) a -> List (Daemon sig) -> Free sig a
90 | SActive x => return x
91 | SYield p => daemons ds [] p
92 | SFork d p => daemons (d :: ds) [] p