@@ -1,6 +1,7 @@
11module Control.Distributed.Process.Internal.Closure.Combinators
2− ( -- * Generic combinators
3− closureApply
2+ ( remoteTable
3+ -- * Generic combinators
4+ , closureApply
45 , closureConst
56 , closureUnit
67 -- * Arrow combinators for processes
@@ -28,16 +29,75 @@ module Control.Distributed.Process.Internal.Closure.Combinators
2829 ) where
2930
3031import Prelude hiding (lookup)
31−import qualified Data.ByteString.Lazy as BS (empty)
3232import Data.Binary (encode)
3333import Data.Typeable (typeOf, Typeable)
34+import Data.Tuple (swap)
35+import Control.Applicative ((<$>))
36+import Control.Monad ((>=>))
3437import Control.Distributed.Process.Internal.Types
3538 ( Closure(..)
3639 , Static(..)
3740 , StaticLabel(..)
3841 , Process
42+ , RemoteTable
3943 )
4044import Control.Distributed.Process.Internal.TypeRep () -- Binary instances
45+import Control.Distributed.Process.Internal.Closure.TH (remotable, mkClosure)
46+import Control.Distributed.Process.Internal.Primitives (unClosure)
47+
48+--------------------------------------------------------------------------------
49+-- TH stuff --
50+--------------------------------------------------------------------------------
51+
52+idUnit :: () -> ()
53+idUnit = id
54+
55+returnProcess :: a -> Process a
56+returnProcess = return
57+
58+kleisliComposeProcess :: (a -> Process b) -> (b -> Process c) -> a -> Process c
59+kleisliComposeProcess = (>=>)
60+
61+firstProcess :: (a -> Process b) -> (a, c) -> Process (b, c)
62+firstProcess f (a, c) = f a >>= \b -> return (b, c)
63+
64+swapProcess :: (a, b) -> Process (b, a)
65+swapProcess = return . swap
66+
67+copyProcess :: a -> Process (a, a)
68+copyProcess x = return (x, x)
69+
70+leftProcess :: (a -> Process b) -> Either a c -> Process (Either b c)
71+leftProcess f (Left a) = Left <$> f a
72+leftProcess _ (Right b) = Right <$> return b
73+
74+mirrorProcess :: Either a b -> Process (Either b a)
75+mirrorProcess (Left x) = Right <$> return x
76+mirrorProcess (Right y) = Left <$> return y
77+
78+untagProcess :: Either a a -> Process a
79+untagProcess (Left x) = return x
80+untagProcess (Right y) = return y
81+
82+applyClosureProcess :: (Typeable a, Typeable b) => (Closure (a -> Process b), a) -> Process b
83+applyClosureProcess (procClosure, a) = do
84+ proc <- unClosure procClosure
85+ proc a
86+
87+remotable [ 'const
88+ , 'idUnit
89+ , 'returnProcess
90+ , 'kleisliComposeProcess
91+ , 'firstProcess
92+ , 'swapProcess
93+ , 'copyProcess
94+ , 'leftProcess
95+ , 'mirrorProcess
96+ , 'untagProcess
97+ ]
98+
99+remoteTable :: RemoteTable -> RemoteTable
100+remoteTable = __remoteTable
41101
42102--------------------------------------------------------------------------------
43103-- Generic closure combinators --
@@ -47,15 +107,11 @@ closureApply :: Closure (a -> b) -> Closure a -> Closure b
47107closureApply (Closure (Static labelf) envf) (Closure (Static labelx) envx) =
48108 Closure (Static ClosureApply) $ encode (labelf, envf, labelx, envx)
49109
50−closureConst :: forall a b. (Typeable a, Typeable b)
51− => Closure (a -> b -> a)
52−closureConst = Closure (Static ClosureConst) (encode $ typeOf aux)
53− where
54− aux :: a -> b -> a
55− aux = undefined
110+closureConst :: (Typeable a, Typeable b) => Closure (a -> b -> a)
111+closureConst = $(mkClosure 'const)
56112
57113closureUnit :: Closure ()
58−closureUnit = Closure (Static ClosureUnit) BS.empty
114+closureUnit = $(mkClosure 'idUnit) ()
59115
60116--------------------------------------------------------------------------------
61117-- Arrow combinators for processes --
@@ -73,37 +129,19 @@ cpElim = flip closureApply closureUnit
73129
74130cpId :: forall a. Typeable a
75131 => CP a a
76−cpId = Closure (Static CpId) (encode $ typeOf aux)
77− where
78− aux :: a -> Process a
79− aux = undefined
132+cpId = $(mkClosure 'returnProcess)
80133
81134cpComp :: forall a b c. (Typeable a, Typeable b, Typeable c)
82135 => CP a b -> CP b c -> CP a c
83−cpComp f g = comp `closureApply` f `closureApply` g
84− where
85− comp :: Closure ((a -> Process b) -> (b -> Process c) -> a -> Process c)
86− comp = Closure (Static CpComp) (encode $ typeOf aux)
87−
88− aux :: (a -> Process b) -> (b -> Process c) -> a -> Process c
89− aux = undefined
136+cpComp f g = $(mkClosure 'kleisliComposeProcess) `closureApply` f `closureApply` g
90137
91138cpFirst :: forall a b c. (Typeable a, Typeable b, Typeable c)
92139 => CP a b -> CP (a, c) (b, c)
93−cpFirst = closureApply first
94− where
95− first :: Closure ((a -> Process b) -> (a, c) -> Process (b, c))
96− first = Closure (Static CpFirst) (encode $ typeOf aux)
97−
98− aux :: (a -> Process b) -> (a, c) -> Process (b, c)
99− aux = undefined
140+cpFirst = closureApply $(mkClosure 'firstProcess)
100141
101142cpSwap :: forall a b. (Typeable a, Typeable b)
102143 => CP (a, b) (b, a)
103−cpSwap = Closure (Static CpSwap) (encode $ typeOf aux)
104− where
105− aux :: (a, b) -> Process (b, a)
106− aux = undefined
144+cpSwap = $(mkClosure 'swapProcess)
107145
108146cpSecond :: (Typeable a, Typeable b, Typeable c)
109147 => CP a b -> CP (c, a) (c, b)
@@ -115,10 +153,7 @@ cpPair f g = cpFirst f `cpComp` cpSecond g
115153
116154cpCopy :: forall a. Typeable a
117155 => CP a (a, a)
118−cpCopy = Closure (Static CpCopy) (encode $ typeOf aux)
119− where
120− aux :: a -> Process (a, a)
121− aux = undefined
156+cpCopy = $(mkClosure 'copyProcess)
122157
123158cpFanOut :: (Typeable a, Typeable b, Typeable c)
124159 => CP a b -> CP a c -> CP a (b, c)
@@ -126,20 +161,11 @@ cpFanOut f g = cpCopy `cpComp` (f `cpPair` g)
126161
127162cpLeft :: forall a b c. (Typeable a, Typeable b, Typeable c)
128163 => CP a b -> CP (Either a c) (Either b c)
129−cpLeft = closureApply left
130− where
131− left :: Closure ((a -> Process b) -> Either a c -> Process (Either b c))
132− left = Closure (Static CpLeft) (encode $ typeOf aux)
133−
134− aux :: (a -> Process b) -> Either a c -> Process (Either b c)
135− aux = undefined
164+cpLeft = closureApply $(mkClosure 'leftProcess)
136165
137166cpMirror :: forall a b. (Typeable a, Typeable b)
138167 => CP (Either a b) (Either b a)
139−cpMirror = Closure (Static CpMirror) (encode $ typeOf aux)
140− where
141− aux :: Either a b -> Process (Either b a)
142− aux = undefined
168+cpMirror = $(mkClosure 'mirrorProcess)
143169
144170cpRight :: forall a b c. (Typeable a, Typeable b, Typeable c)
145171 => CP a b -> CP (Either c a) (Either c b)
@@ -151,10 +177,7 @@ cpEither f g = cpLeft f `cpComp` cpRight g
151177
152178cpUntag :: forall a. Typeable a
153179 => CP (Either a a) a
154−cpUntag = Closure (Static CpUntag) (encode $ typeOf aux)
155− where
156− aux :: Either a a -> Process a
157− aux = undefined
180+cpUntag = $(mkClosure 'untagProcess)
158181
159182cpFanIn :: (Typeable a, Typeable b, Typeable c)
160183 => CP a c -> CP b c -> CP (Either a b) c