@@ -43,17 +43,36 @@ module Control.Distributed.Process.Closure
43 ( -- * Primitive closures
43 ( -- * Primitive closures
45 , mkClosure
45 , mkClosure
46+ -- * Generic closure combinators
46− -- * Closure combinators
50+ -- * Arrow combinators for processes
47− , applyClosure
51+ , CP
48− , liftedBind
52+ , cpIntro
49− , liftedConst
53+ , cpElim
51− , weakenCP
55+ , cpComp
69+ -- * Derived combinators for processes
55import Prelude hiding (lookup)
74import Prelude hiding (lookup)
56−import Data.ByteString.Lazy (ByteString)
75+import Data.ByteString.Lazy (ByteString, empty)
57import Data.Binary (encode, decode)
76import Data.Binary (encode, decode)
58import Data.Typeable (typeOf, Typeable)
77import Data.Typeable (typeOf, Typeable)
59import Control.Applicative ((<$>))
78import Control.Applicative ((<$>))
@@ -87,6 +106,7 @@ import Control.Distributed.Process.Internal.Types
87 ( RemoteTable
106 ( RemoteTable
88 , Closure(..)
107 , Closure(..)
89 , Static(..)
108 , Static(..)
90 , Process
110 , Process
91 , ProcessId
111 , ProcessId
92 , CallReply(..)
112 , CallReply(..)
@@ -113,35 +133,143 @@ mkClosure :: Name -> Q Exp
113mkClosure = varE . closureName
133mkClosure = varE . closureName
115--------------------------------------------------------------------------------
135--------------------------------------------------------------------------------
116−-- Closure combinators --
136+-- Generic closure combinators --
117--------------------------------------------------------------------------------
137--------------------------------------------------------------------------------
119−applyClosure :: Closure (a -> b) -> Closure a -> Closure b
139+closureApply :: Closure (a -> b) -> Closure a -> Closure b
120−applyClosure (Closure (Static labelf) envf) (Closure (Static labelx) envx) =
140+closureApply (Closure (Static labelf) envf) (Closure (Static labelx) envx) =
121− Closure (Static "$applyClosure") $ encode (labelf, envf, labelx, envx)
141+ Closure (Static ClosureApply) $ encode (labelf, envf, labelx, envx)
123−liftedBind :: forall a b. (Typeable a, Typeable b)
143+closureConst :: forall a b. (Typeable a, Typeable b)
124− => Closure (Process a -> (a -> Process b) -> Process b)
144+ => Closure (a -> b -> a)
125−liftedBind = Closure (Static "$liftedBind") (encode typ)
145+closureConst = Closure (Static ClosureConst) (encode $ typeOf aux)
127− typ = typeOf (undefined :: Process a -> (a -> Process b) -> Process b)
147+ aux :: a -> b -> a
150+closureUnit :: Closure ()
151+closureUnit = Closure (Static ClosureUnit) empty
153+--------------------------------------------------------------------------------
154+-- Arrow combinators for processes --
155+--------------------------------------------------------------------------------
157+type CP a b = Closure (a -> Process b)
159+cpIntro :: (Typeable a, Typeable b)
160+ => Closure (Process b) -> CP a b
161+cpIntro = closureApply closureConst
164+ => CP () a -> Closure (Process a)
165+cpElim = flip closureApply closureUnit
129−liftedConst :: forall a b. (Typeable a, Typeable b)
167+cpId :: forall a. Typeable a
130− => Closure (a -> b -> a)
168+ => CP a a
131−liftedConst = Closure (Static "$liftedConst") (encode typ)
169+cpId = Closure (Static CpId) (encode $ typeOf aux)
171+ aux :: a -> Process a
133− typ = typeOf (undefined :: a -> b -> a)
172+ aux = undefined
174+cpComp :: forall a b c. (Typeable a, Typeable b, Typeable c)
175+ => CP a b -> CP b c -> CP a c
176+cpComp f g = comp `closureApply` f `closureApply` g
178+ comp :: Closure ((a -> Process b) -> (b -> Process c) -> (a -> Process c))
179+ comp = Closure (Static CpComp) (encode $ typeOf aux)
181+ aux :: (a -> Process b) -> (b -> Process c) -> (a -> Process c)
184+cpFirst :: forall a b c. (Typeable a, Typeable b, Typeable c)
185+ => CP a b -> CP (a, c) (b, c)
186+cpFirst = closureApply first
188+ first :: Closure ((a -> Process b) -> (a, c) -> Process (b, c))
189+ first = Closure (Static CpFirst) (encode $ typeOf aux)
191+ aux :: (a -> Process b) -> (a, c) -> Process (b, c)
194+cpSwap :: forall a b. (Typeable a, Typeable b)
196+cpSwap = Closure (Static CpSwap) (encode $ typeOf aux)
198+ aux :: (a, b) -> Process (b, a)
201+cpSecond :: (Typeable a, Typeable b, Typeable c)
202+ => CP a b -> CP (c, a) (c, b)
203+cpSecond f = cpSwap `cpComp` cpFirst f `cpComp` cpSwap
205+cpPair :: (Typeable a, Typeable a', Typeable b, Typeable b')
206+ => CP a b -> CP a' b' -> CP (a, a') (b, b')
207+cpPair f g = cpFirst f `cpComp` cpSecond g
209+cpCopy :: forall a. Typeable a
211+cpCopy = Closure (Static CpCopy) (encode $ typeOf aux)
213+ aux :: a -> Process (a, a)
216+cpFanOut :: (Typeable a, Typeable b, Typeable c)
217+ => CP a b -> CP a c -> CP a (b, c)
218+cpFanOut f g = cpCopy `cpComp` (f `cpPair` g)
220+cpLeft :: forall a b c. (Typeable a, Typeable b, Typeable c)
221+ => CP a b -> CP (Either a c) (Either b c)
222+cpLeft = closureApply left
224+ left :: Closure ((a -> Process b) -> Either a c -> Process (Either b c))
225+ left = Closure (Static CpLeft) (encode $ typeOf aux)
227+ aux :: (a -> Process b) -> Either a c -> Process (Either b c)
135−bindCP :: (Typeable a, Typeable b)
230+cpMirror :: forall a b. (Typeable a, Typeable b)
136− => Closure (Process a) -> Closure (a -> Process b) -> Closure (Process b)
231+ => CP (Either a b) (Either b a)
137−bindCP x f = liftedBind `applyClosure` x `applyClosure` f
232+cpMirror = Closure (Static CpMirror) (encode $ typeOf aux)
234+ aux :: Either a b -> Process (Either b a)
237+cpRight :: forall a b c. (Typeable a, Typeable b, Typeable c)
238+ => CP a b -> CP (Either c a) (Either c b)
239+cpRight f = cpMirror `cpComp` cpLeft f `cpComp` cpMirror
241+cpEither :: (Typeable a, Typeable a', Typeable b, Typeable b')
242+ => CP a b -> CP a' b' -> CP (Either a a') (Either b b')
243+cpEither f g = cpLeft f `cpComp` cpRight g
245+cpUntag :: forall a. Typeable a
246+ => CP (Either a a) a
247+cpUntag = Closure (Static CpUntag) (encode $ typeOf aux)
249+ aux :: Either a a -> Process a
139−weakenCP :: (Typeable a, Typeable b)
252+cpFanIn :: (Typeable a, Typeable b, Typeable c)
253+ => CP a c -> CP b c -> CP (Either a b) c
254+cpFanIn f g = (f `cpEither` g) `cpComp` cpUntag
256+cpApply :: forall a b. (Typeable a, Typeable b)
258+cpApply = Closure (Static CpApply) (encode $ typeOf aux)
140− => Closure (Process b) -> Closure (a -> Process b)
260+ aux :: (Closure (a -> Process b), a) -> Process b
141−weakenCP = applyClosure liftedConst
261+ aux = undefined
263+--------------------------------------------------------------------------------
264+-- Some derived operators for processes --
265+--------------------------------------------------------------------------------
267+cpBind :: (Typeable a, Typeable b)
268+ => Closure (Process a) -> Closure (a -> Process b) -> Closure (Process b)
269+cpBind x f = cpElim $ cpIntro x `cpComp` f
143−seqCP :: Closure (Process ()) -> Closure (Process ()) -> Closure (Process ())
271+cpSeq :: Closure (Process ()) -> Closure (Process ()) -> Closure (Process ())
144−seqCP p q = bindCP p (weakenCP q)
272+cpSeq p q = p `cpBind` cpIntro q
146--------------------------------------------------------------------------------
274--------------------------------------------------------------------------------
147-- Internal (Template Haskell) --
275-- Internal (Template Haskell) --
@@ -190,7 +318,7 @@ generateClosure :: Name -> Q Type -> Q Type -> Q ([Dec], String)
190generateClosure n arg res = do
318generateClosure n arg res = do
191 closure <- sequence
319 closure <- sequence
192 [ sigD (closureName n) [t| $arg -> Closure $res |]
320 [ sigD (closureName n) [t| $arg -> Closure $res |]
193− , sfnD (closureName n) [| Closure (Static $(stringE label)) . encode |]
321+ , sfnD (closureName n) [| Closure (Static (UserStatic ($(stringE label)))) . encode |]
195 return (closure, label)
323 return (closure, label)