1{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE RankNTypes #-}
3module Control.Distributed.Process.Internal.Closure.BuiltIn
6 -- * Static dictionaries and associated operations
11 -- * Some static values
13 -- * The CP type and associated combinators
20 -- * CP versions of Cloud Haskell primitives
21 , decodeProcessIdStatic
28 -- * Support for some CH operations
33import Data.ByteString.Lazy (ByteString)
34import Data.Binary (decode, encode)
35import Data.Rank1Typeable (Typeable, ANY, ANY1, ANY2, ANY3, ANY4)
36import Data.Rank1Dynamic (toDynamic)
37import Control.Distributed.Static
50import Control.Distributed.Process.Serializable
51 ( SerializableDict(..)
54import Control.Distributed.Process.Internal.Types
59 , ProcessMonitorNotification(ProcessMonitorNotification)
61import Control.Distributed.Process.Internal.Primitives
75--------------------------------------------------------------------------------
77--------------------------------------------------------------------------------
79remoteTable :: RemoteTable -> RemoteTable
81 registerStatic "$decodeDict" (toDynamic (decodeDict :: SerializableDict ANY -> ByteString -> ANY))
82 . registerStatic "$sdictUnit" (toDynamic (SerializableDict :: SerializableDict ()))
83 . registerStatic "$sdictProcessId" (toDynamic (SerializableDict :: SerializableDict ProcessId))
84 . registerStatic "$sdictSendPort_" (toDynamic (sdictSendPort_ :: SerializableDict ANY -> SerializableDict (SendPort ANY)))
85 . registerStatic "$returnProcess" (toDynamic (return :: ANY -> Process ANY))
86 . registerStatic "$seqProcess" (toDynamic ((>>) :: Process ANY1 -> Process ANY2 -> Process ANY2))
87 . registerStatic "$bindProcess" (toDynamic ((>>=) :: Process ANY1 -> (ANY1 -> Process ANY2) -> Process ANY2))
88 . registerStatic "$decodeProcessId" (toDynamic (decode :: ByteString -> ProcessId))
89 . registerStatic "$link" (toDynamic link)
90 . registerStatic "$unlink" (toDynamic unlink)
91 . registerStatic "$relay" (toDynamic relay)
92 . registerStatic "$sendDict" (toDynamic (sendDict :: SerializableDict ANY -> ProcessId -> ANY -> Process ()))
93 . registerStatic "$expectDict" (toDynamic (expectDict :: SerializableDict ANY -> Process ANY))
94 . registerStatic "$newChanDict" (toDynamic (newChanDict :: SerializableDict ANY -> Process (SendPort ANY, ReceivePort ANY)))
95 . registerStatic "$cpSplit" (toDynamic (cpSplit :: (ANY1 -> Process ANY3) -> (ANY2 -> Process ANY4) -> (ANY1, ANY2) -> Process (ANY3, ANY4)))
96 . registerStatic "$snd" (toDynamic (snd :: (ANY1, ANY2) -> ANY2))
97 . registerStatic "$delay" (toDynamic delay)
99 decodeDict :: forall a. SerializableDict a -> ByteString -> a
100 decodeDict SerializableDict = decode
102 sdictSendPort_ :: forall a. SerializableDict a -> SerializableDict (SendPort a)
103 sdictSendPort_ SerializableDict = SerializableDict
105 sendDict :: forall a. SerializableDict a -> ProcessId -> a -> Process ()
106 sendDict SerializableDict = send
108 expectDict :: forall a. SerializableDict a -> Process a
109 expectDict SerializableDict = expect
111 newChanDict :: forall a. SerializableDict a -> Process (SendPort a, ReceivePort a)
112 newChanDict SerializableDict = newChan
114 cpSplit :: forall a b c d. (a -> Process c) -> (b -> Process d) -> (a, b) -> Process (c, d)
115 cpSplit f g (a, b) = do
120--------------------------------------------------------------------------------
121-- Static dictionaries and associated operations --
122--------------------------------------------------------------------------------
124-- | Static decoder, given a static serialization dictionary.
126-- See module documentation of "Control.Distributed.Process.Closure" for an
128staticDecode :: Typeable a => Static (SerializableDict a) -> Static (ByteString -> a)
129staticDecode dict = decodeDictStatic `staticApply` dict
131 decodeDictStatic :: Typeable a => Static (SerializableDict a -> ByteString -> a)
132 decodeDictStatic = staticLabel "$decodeDict"
134-- | Serialization dictionary for '()'
135sdictUnit :: Static (SerializableDict ())
136sdictUnit = staticLabel "$sdictUnit"
138-- | Serialization dictionary for 'ProcessId'
139sdictProcessId :: Static (SerializableDict ProcessId)
140sdictProcessId = staticLabel "$sdictProcessId"
142-- | Serialization dictionary for 'SendPort'
143sdictSendPort :: Typeable a
144 => Static (SerializableDict a) -> Static (SerializableDict (SendPort a))
145sdictSendPort = staticApply (staticLabel "$sdictSendPort_")
147--------------------------------------------------------------------------------
149--------------------------------------------------------------------------------
151sndStatic :: Static ((a, b) -> b)
152sndStatic = staticLabel "$snd"
154--------------------------------------------------------------------------------
155-- The CP type and associated combinators --
156--------------------------------------------------------------------------------
158-- | @CP a b@ is a process with input of type @a@ and output of type @b@
159type CP a b = Closure (a -> Process b)
161returnProcessStatic :: Typeable a => Static (a -> Process a)
162returnProcessStatic = staticLabel "$returnProcess"
164-- | 'CP' version of 'Control.Category.id'
165idCP :: Typeable a => CP a a
166idCP = staticClosure returnProcessStatic
168-- | 'CP' version of ('Control.Arrow.***')
169splitCP :: (Typeable a, Typeable b, Typeable c, Typeable d)
170 => CP a c -> CP b d -> CP (a, b) (c, d)
171splitCP p q = cpSplitStatic `closureApplyStatic` p `closureApply` q
173 cpSplitStatic :: Static ((a -> Process c) -> (b -> Process d) -> (a, b) -> Process (c, d))
174 cpSplitStatic = staticLabel "$cpSplit"
176-- | 'CP' version of 'Control.Monad.return'
177returnCP :: forall a. Serializable a
178 => Static (SerializableDict a) -> a -> Closure (Process a)
179returnCP dict x = closure decoder (encode x)
181 decoder :: Static (ByteString -> Process a)
182 decoder = returnProcessStatic
186-- | 'CP' version of ('Control.Monad.>>')
187seqCP :: (Typeable a, Typeable b)
188 => Closure (Process a) -> Closure (Process b) -> Closure (Process b)
189seqCP p q = seqProcessStatic `closureApplyStatic` p `closureApply` q
191 seqProcessStatic :: (Typeable a, Typeable b)
192 => Static (Process a -> Process b -> Process b)
193 seqProcessStatic = staticLabel "$seqProcess"
195-- | (Not quite the) 'CP' version of ('Control.Monad.>>=')
196bindCP :: forall a b. (Typeable a, Typeable b)
197 => Closure (Process a) -> CP a b -> Closure (Process b)
198bindCP x f = bindProcessStatic `closureApplyStatic` x `closureApply` f
200 bindProcessStatic :: (Typeable a, Typeable b)
201 => Static (Process a -> (a -> Process b) -> Process b)
202 bindProcessStatic = staticLabel "$bindProcess"
204--------------------------------------------------------------------------------
205-- CP versions of Cloud Haskell primitives --
206--------------------------------------------------------------------------------
208decodeProcessIdStatic :: Static (ByteString -> ProcessId)
209decodeProcessIdStatic = staticLabel "$decodeProcessId"
211-- | 'CP' version of 'link'
212cpLink :: ProcessId -> Closure (Process ())
213cpLink = closure (linkStatic `staticCompose` decodeProcessIdStatic) . encode
215 linkStatic :: Static (ProcessId -> Process ())
216 linkStatic = staticLabel "$link"
218-- | 'CP' version of 'unlink'
219cpUnlink :: ProcessId -> Closure (Process ())
220cpUnlink = closure (unlinkStatic `staticCompose` decodeProcessIdStatic) . encode
222 unlinkStatic :: Static (ProcessId -> Process ())
223 unlinkStatic = staticLabel "$unlink"
225-- | 'CP' version of 'send'
226cpSend :: forall a. Typeable a
227 => Static (SerializableDict a) -> ProcessId -> CP a ()
228cpSend dict pid = closure decoder (encode pid)
230 decoder :: Static (ByteString -> a -> Process ())
231 decoder = (sendDictStatic `staticApply` dict)
233 decodeProcessIdStatic
235 sendDictStatic :: Typeable a
236 => Static (SerializableDict a -> ProcessId -> a -> Process ())
237 sendDictStatic = staticLabel "$sendDict"
239-- | 'CP' version of 'expect'
240cpExpect :: Typeable a => Static (SerializableDict a) -> Closure (Process a)
241cpExpect dict = staticClosure (expectDictStatic `staticApply` dict)
243 expectDictStatic :: Typeable a => Static (SerializableDict a -> Process a)
244 expectDictStatic = staticLabel "$expectDict"
246-- | 'CP' version of 'newChan'
247cpNewChan :: Typeable a
248 => Static (SerializableDict a)
249 -> Closure (Process (SendPort a, ReceivePort a))
250cpNewChan dict = staticClosure (newChanDictStatic `staticApply` dict)
252 newChanDictStatic :: Typeable a
253 => Static (SerializableDict a -> Process (SendPort a, ReceivePort a))
254 newChanDictStatic = staticLabel "$newChanDict"
256-- | 'CP' version of 'relay'
257cpRelay :: ProcessId -> Closure (Process ())
258cpRelay = closure (relayStatic `staticCompose` decodeProcessIdStatic) . encode
260 relayStatic :: Static (ProcessId -> Process ())
261 relayStatic = staticLabel "$relay"
263-- TODO: move cpEnableTraceRemote into Trace/Primitives.hs
265cpEnableTraceRemote :: ProcessId -> Closure (Process ())
267 closure (enableTraceStatic `staticCompose` decodeProcessIdStatic) . encode
269 enableTraceStatic :: Static (ProcessId -> Process ())
270 enableTraceStatic = staticLabel "$enableTraceRemote"
272--------------------------------------------------------------------------------
273-- Support for spawn --
274--------------------------------------------------------------------------------
276-- | @delay them p@ is a process that waits for a signal (a message of type @()@)
277-- from 'them' (origin is not verified) before proceeding as @p@. In order to
278-- avoid waiting forever, @delay them p@ monitors 'them'. If it receives a
279-- monitor message instead it simply terminates.
280delay :: ProcessId -> Process () -> Process ()
283 let sameRef (ProcessMonitorNotification ref' _ _) = ref == ref'
285 match $ \() -> unmonitor ref >> p
286 , matchIf sameRef $ \_ -> return ()
289-- | 'CP' version of 'delay'
290cpDelay :: ProcessId -> Closure (Process ()) -> Closure (Process ())
291cpDelay = closureApply . cpDelay'
293 cpDelay' :: ProcessId -> Closure (Process () -> Process ())
294 cpDelay' pid = closure decoder (encode pid)
296 decoder :: Static (ByteString -> Process () -> Process ())
297 decoder = delayStatic `staticCompose` decodeProcessIdStatic
299 delayStatic :: Static (ProcessId -> Process () -> Process ())
300 delayStatic = staticLabel "$delay"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list