@@ -43,17 +43,36 @@ module Control.Distributed.Process.Closure
4343 ( -- * Primitive closures
4444 remotable
4545 , mkClosure
46− -- * Closure combinators
47− , applyClosure
48− , liftedBind
49− , liftedConst
50− , bindCP
51− , weakenCP
52− , seqCP
46+ -- * Generic closure combinators
47+ , closureApply
48+ , closureConst
49+ , closureUnit
50+ -- * Arrow combinators for processes
51+ , CP
52+ , cpIntro
53+ , cpElim
54+ , cpId
55+ , cpComp
56+ , cpFirst
57+ , cpSwap
58+ , cpSecond
59+ , cpPair
60+ , cpCopy
61+ , cpFanOut
62+ , cpLeft
63+ , cpMirror
64+ , cpRight
65+ , cpEither
66+ , cpUntag
67+ , cpFanIn
68+ , cpApply
69+ -- * Derived combinators for processes
70+ , cpBind
71+ , cpSeq
5372 ) where
5473
5574import Prelude hiding (lookup)
56−import Data.ByteString.Lazy (ByteString)
75+import Data.ByteString.Lazy (ByteString, empty)
5776import Data.Binary (encode, decode)
5877import Data.Typeable (typeOf, Typeable)
5978import Control.Applicative ((<$>))
@@ -87,6 +106,7 @@ import Control.Distributed.Process.Internal.Types
87106 ( RemoteTable
88107 , Closure(..)
89108 , Static(..)
109+ , StaticLabel(..)
90110 , Process
91111 , ProcessId
92112 , CallReply(..)
@@ -113,35 +133,143 @@ mkClosure :: Name -> Q Exp
113133mkClosure = varE . closureName
114134
115135--------------------------------------------------------------------------------
116−-- Closure combinators --
136+-- Generic closure combinators --
117137--------------------------------------------------------------------------------
118138
119−applyClosure :: Closure (a -> b) -> Closure a -> Closure b
120−applyClosure (Closure (Static labelf) envf) (Closure (Static labelx) envx) =
121− Closure (Static "$applyClosure") $ encode (labelf, envf, labelx, envx)
139+closureApply :: Closure (a -> b) -> Closure a -> Closure b
140+closureApply (Closure (Static labelf) envf) (Closure (Static labelx) envx) =
141+ Closure (Static ClosureApply) $ encode (labelf, envf, labelx, envx)
122142
123−liftedBind :: forall a b. (Typeable a, Typeable b)
124− => Closure (Process a -> (a -> Process b) -> Process b)
125−liftedBind = Closure (Static "$liftedBind") (encode typ)
126− where
127− typ = typeOf (undefined :: Process a -> (a -> Process b) -> Process b)
143+closureConst :: forall a b. (Typeable a, Typeable b)
144+ => Closure (a -> b -> a)
145+closureConst = Closure (Static ClosureConst) (encode $ typeOf aux)
146+ where
147+ aux :: a -> b -> a
148+ aux = undefined
149+
150+closureUnit :: Closure ()
151+closureUnit = Closure (Static ClosureUnit) empty
152+
153+--------------------------------------------------------------------------------
154+-- Arrow combinators for processes --
155+--------------------------------------------------------------------------------
128156
129−liftedConst :: forall a b. (Typeable a, Typeable b)
130− => Closure (a -> b -> a)
131−liftedConst = Closure (Static "$liftedConst") (encode typ)
157+type CP a b = Closure (a -> Process b)
158+
159+cpIntro :: (Typeable a, Typeable b)
160+ => Closure (Process b) -> CP a b
161+cpIntro = closureApply closureConst
162+
163+cpElim :: Typeable a
164+ => CP () a -> Closure (Process a)
165+cpElim = flip closureApply closureUnit
166+
167+cpId :: forall a. Typeable a
168+ => CP a a
169+cpId = Closure (Static CpId) (encode $ typeOf aux)
132170 where
133− typ = typeOf (undefined :: a -> b -> a)
171+ aux :: a -> Process a
172+ aux = undefined
134173
135−bindCP :: (Typeable a, Typeable b)
136− => Closure (Process a) -> Closure (a -> Process b) -> Closure (Process b)
137−bindCP x f = liftedBind `applyClosure` x `applyClosure` f
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
177+ where
178+ comp :: Closure ((a -> Process b) -> (b -> Process c) -> (a -> Process c))
179+ comp = Closure (Static CpComp) (encode $ typeOf aux)
180+
181+ aux :: (a -> Process b) -> (b -> Process c) -> (a -> Process c)
182+ aux = undefined
183+
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
187+ where
188+ first :: Closure ((a -> Process b) -> (a, c) -> Process (b, c))
189+ first = Closure (Static CpFirst) (encode $ typeOf aux)
190+
191+ aux :: (a -> Process b) -> (a, c) -> Process (b, c)
192+ aux = undefined
193+
194+cpSwap :: forall a b. (Typeable a, Typeable b)
195+ => CP (a, b) (b, a)
196+cpSwap = Closure (Static CpSwap) (encode $ typeOf aux)
197+ where
198+ aux :: (a, b) -> Process (b, a)
199+ aux = undefined
200+
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
204+
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
208+
209+cpCopy :: forall a. Typeable a
210+ => CP a (a, a)
211+cpCopy = Closure (Static CpCopy) (encode $ typeOf aux)
212+ where
213+ aux :: a -> Process (a, a)
214+ aux = undefined
215+
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)
219+
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
223+ where
224+ left :: Closure ((a -> Process b) -> Either a c -> Process (Either b c))
225+ left = Closure (Static CpLeft) (encode $ typeOf aux)
226+
227+ aux :: (a -> Process b) -> Either a c -> Process (Either b c)
228+ aux = undefined
229+
230+cpMirror :: forall a b. (Typeable a, Typeable b)
231+ => CP (Either a b) (Either b a)
232+cpMirror = Closure (Static CpMirror) (encode $ typeOf aux)
233+ where
234+ aux :: Either a b -> Process (Either b a)
235+ aux = undefined
236+
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
240+
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
138244
139−weakenCP :: (Typeable a, Typeable b)
140− => Closure (Process b) -> Closure (a -> Process b)
141−weakenCP = applyClosure liftedConst
245+cpUntag :: forall a. Typeable a
246+ => CP (Either a a) a
247+cpUntag = Closure (Static CpUntag) (encode $ typeOf aux)
248+ where
249+ aux :: Either a a -> Process a
250+ aux = undefined
251+
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
255+
256+cpApply :: forall a b. (Typeable a, Typeable b)
257+ => CP (CP a b, a) b
258+cpApply = Closure (Static CpApply) (encode $ typeOf aux)
259+ where
260+ aux :: (Closure (a -> Process b), a) -> Process b
261+ aux = undefined
262+
263+--------------------------------------------------------------------------------
264+-- Some derived operators for processes --
265+--------------------------------------------------------------------------------
266+
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
142270
143−seqCP :: Closure (Process ()) -> Closure (Process ()) -> Closure (Process ())
144−seqCP p q = bindCP p (weakenCP q)
271+cpSeq :: Closure (Process ()) -> Closure (Process ()) -> Closure (Process ())
272+cpSeq p q = p `cpBind` cpIntro q
145273
146274--------------------------------------------------------------------------------
147275-- Internal (Template Haskell) --
@@ -190,7 +318,7 @@ generateClosure :: Name -> Q Type -> Q Type -> Q ([Dec], String)
190318generateClosure n arg res = do
191319 closure <- sequence
192320 [ 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 |]
194322 ]
195323 return (closure, label)
196324 where