-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Compositional, type-safe, polymorphic static values and closures
--   
--   <i>Towards Haskell in the Cloud</i> (Epstein et al, Haskell Symposium
--   2011) introduces the concept of <i>static</i> values: values that are
--   known at compile time. In a distributed setting where all nodes are
--   running the same executable, static values can be serialized simply by
--   transmitting a code pointer to the value. This however requires
--   special compiler support, which is not yet available in ghc. We can
--   mimick the behaviour by keeping an explicit mapping
--   (<a>RemoteTable</a>) from labels to values (and making sure that all
--   distributed nodes are using the same <a>RemoteTable</a>). In this
--   module we implement this mimickry and various extensions: type safety
--   (including for polymorphic static values) and compositionality.
@package distributed-static
@version 0.3.5.0


-- | <i>Towards Haskell in the Cloud</i> (Epstein et al, Haskell Symposium
--   2011) introduces the concept of <i>static</i> values: values that are
--   known at compile time. In a distributed setting where all nodes are
--   running the same executable, static values can be serialized simply by
--   transmitting a code pointer to the value. This however requires
--   special compiler support, which is not yet available in ghc. We can
--   mimick the behaviour by keeping an explicit mapping
--   (<a>RemoteTable</a>) from labels to values (and making sure that all
--   distributed nodes are using the same <a>RemoteTable</a>). In this
--   module we implement this mimickry and various extensions.
--   
--   <ul>
--   <li><i>Dynamic type checking</i></li>
--   </ul>
--   
--   The paper stipulates that <a>Static</a> values should have a free
--   <a>Binary</a> instance:
--   
--   <pre>
--   instance Binary (Static a)
--   </pre>
--   
--   This however is not (runtime) type safe: for instance, what would be
--   the behaviour of
--   
--   <pre>
--   f :: Static Int -&gt; Static Bool
--   f = decode . encode
--   </pre>
--   
--   For this reason we work only with <a>Typeable</a> terms in this
--   module, and implement runtime checks
--   
--   <pre>
--   instance Typeable a =&gt; Binary (Static a)
--   </pre>
--   
--   The above function <tt>f</tt> typechecks but throws an exception if
--   executed. The type representation we use, however, is not the standard
--   <a>TypeRep</a> from <a>Data.Typeable</a> but <a>TypeRep</a> from
--   <a>Data.Rank1Typeable</a>. This means that we can represent
--   polymorphic static values (see below for an example).
--   
--   Since the runtime mapping (<a>RemoteTable</a>) contains values of
--   different types, it maps labels (<a>String</a>s) to <a>Dynamic</a>
--   values. Again, we use the implementation from <a>Data.Rank1Dynamic</a>
--   so that we can store polymorphic dynamic values.
--   
--   <ul>
--   <li><i>Compositionality</i></li>
--   </ul>
--   
--   Static values as described in the paper are not compositional: there
--   is no way to combine two static values and get a static value out of
--   it. This makes sense when interpreting static strictly as <i>known at
--   compile time</i>, but it severely limits expressiveness. However, the
--   main motivation for 'static' is not that they are known at compile
--   time but rather that <i>they provide a free</i> <a>Binary</a>
--   <i>instance</i>. We therefore provide two basic constructors for
--   <a>Static</a> values:
--   
--   <pre>
--   staticLabel :: String -&gt; Static a
--   staticApply :: Static (a -&gt; b) -&gt; Static a -&gt; Static b
--   </pre>
--   
--   The first constructor refers to a label in a <a>RemoteTable</a>. The
--   second allows to apply a static function to a static argument, and
--   makes <a>Static</a> compositional: once we have <a>staticApply</a> we
--   can implement numerous derived combinators on <a>Static</a> values (we
--   define a few in this module; see <a>staticCompose</a>,
--   <a>staticSplit</a>, and <a>staticConst</a>).
--   
--   <ul>
--   <li><i>Closures</i></li>
--   </ul>
--   
--   Closures in functional programming arise when we partially apply a
--   function. A closure is a code pointer together with a runtime data
--   structure that represents the value of the free variables of the
--   function. A <a>Closure</a> represents these closures explicitly so
--   that they can be serialized:
--   
--   <pre>
--   data Closure a = Closure (Static (ByteString -&gt; a)) ByteString
--   </pre>
--   
--   See <i>Towards Haskell in the Cloud</i> for the rationale behind
--   representing the function closure environment in serialized
--   (<a>ByteString</a>) form. Any static value can trivially be turned
--   into a <a>Closure</a> (<a>staticClosure</a>). Moreover, since
--   <a>Static</a> is now compositional, we can also define derived
--   operators on <a>Closure</a> values (<a>closureApplyStatic</a>,
--   <a>closureApply</a>, <a>closureCompose</a>, <a>closureSplit</a>).
--   
--   <ul>
--   <li><i>Monomorphic example</i></li>
--   </ul>
--   
--   Suppose we are working in the context of some distributed environment,
--   with a monadic type <tt>Process</tt> representing processes,
--   <tt>NodeId</tt> representing node addresses and <tt>ProcessId</tt>
--   representing process addresses. Suppose further that we have a
--   primitive
--   
--   <pre>
--   sendInt :: ProcessId -&gt; Int -&gt; Process ()
--   </pre>
--   
--   We might want to define
--   
--   <pre>
--   sendIntClosure :: ProcessId -&gt; Closure (Int -&gt; Process ())
--   </pre>
--   
--   In order to do that, we need a static version of <tt>send</tt>, and a
--   static decoder for <tt>ProcessId</tt>:
--   
--   <pre>
--   sendIntStatic :: Static (ProcessId -&gt; Int -&gt; Process ())
--   sendIntStatic = staticLabel "$send"
--   </pre>
--   
--   <pre>
--   decodeProcessIdStatic :: Static (ByteString -&gt; Int)
--   decodeProcessIdStatic = staticLabel "$decodeProcessId"
--   </pre>
--   
--   where of course we have to make sure to use an appropriate
--   <a>RemoteTable</a>:
--   
--   <pre>
--   rtable :: RemoteTable
--   rtable = registerStatic "$send" (toDynamic sendInt)
--          . registerStatic "$decodeProcessId" (toDynamic (decode :: ByteString -&gt; Int))
--          $ initRemoteTable
--   </pre>
--   
--   We can now define <tt>sendIntClosure</tt>:
--   
--   <pre>
--   sendIntClosure :: ProcessId -&gt; Closure (Int -&gt; Process ())
--   sendIntClosure pid = closure decoder (encode pid)
--     where
--       decoder :: Static (ByteString -&gt; Int -&gt; Process ())
--       decoder = sendIntStatic `staticCompose` decodeProcessIdStatic
--   </pre>
--   
--   <ul>
--   <li><i>Polymorphic example</i></li>
--   </ul>
--   
--   Suppose we wanted to define a primitive
--   
--   <pre>
--   sendIntResult :: ProcessId -&gt; Closure (Process Int) -&gt; Closure (Process ())
--   </pre>
--   
--   which turns a process that computes an integer into a process that
--   computes the integer and then sends it someplace else.
--   
--   We can define
--   
--   <pre>
--   bindStatic :: (Typeable a, Typeable b) =&gt; Static (Process a -&gt; (a -&gt; Process b) -&gt; Process b)
--   bindStatic = staticLabel "$bind"
--   </pre>
--   
--   provided that we register this label:
--   
--   <pre>
--   rtable :: RemoteTable
--   rtable = ...
--          . registerStatic "$bind" ((&gt;&gt;=) :: Process ANY1 -&gt; (ANY1 -&gt; Process ANY2) -&gt; Process ANY2)
--          $ initRemoteTable
--   </pre>
--   
--   (Note that we are using the special <a>ANY1</a> and <a>ANY2</a> types
--   from <a>Data.Rank1Typeable</a> to represent this polymorphic value.)
--   Once we have a static bind we can define
--   
--   <pre>
--   sendIntResult :: ProcessId -&gt; Closure (Process Int) -&gt; Closure (Process ())
--   sendIntResult pid cl = bindStatic `closureApplyStatic` cl `closureApply` sendIntClosure pid
--   </pre>
--   
--   <ul>
--   <li><i>Dealing with qualified types</i></li>
--   </ul>
--   
--   In the above we were careful to avoid qualified types. Suppose that we
--   have instead
--   
--   <pre>
--   send :: Binary a =&gt; ProcessId -&gt; a -&gt; Process ()
--   </pre>
--   
--   If we now want to define <tt>sendClosure</tt>, analogous to
--   <tt>sendIntClosure</tt> above, we somehow need to include the
--   <a>Binary</a> instance in the closure -- after all, we can ship this
--   closure someplace else, where it needs to accept an <tt>a</tt>,
--   <i>then encode it</i>, and send it off. In order to do this, we need
--   to turn the Binary instance into an explicit dictionary:
--   
--   <pre>
--   data BinaryDict a where
--     BinaryDict :: Binary a =&gt; BinaryDict a
--   
--   sendDict :: BinaryDict a -&gt; ProcessId -&gt; a -&gt; Process ()
--   sendDict BinaryDict = send
--   </pre>
--   
--   Now <tt>sendDict</tt> is a normal polymorphic value:
--   
--   <pre>
--   sendDictStatic :: Static (BinaryDict a -&gt; ProcessId -&gt; a -&gt; Process ())
--   sendDictStatic = staticLabel "$sendDict"
--   
--   rtable :: RemoteTable
--   rtable = ...
--          . registerStatic "$sendDict" (sendDict :: BinaryDict ANY -&gt; ProcessId -&gt; ANY -&gt; Process ())
--          $ initRemoteTable
--   </pre>
--   
--   so that we can define
--   
--   <pre>
--   sendClosure :: Static (BinaryDict a) -&gt; Process a -&gt; Closure (a -&gt; Process ())
--   sendClosure dict pid = closure decoder (encode pid)
--     where
--       decoder :: Static (ByteString -&gt; a -&gt; Process ())
--       decoder = (sendDictStatic `staticApply` dict) `staticCompose` decodeProcessIdStatic
--   </pre>
--   
--   <ul>
--   <li><i>Word of Caution</i></li>
--   </ul>
--   
--   You should not <i>define</i> functions on <tt>ANY</tt> and co. For
--   example, the following definition of <tt>rtable</tt> is incorrect:
--   
--   <pre>
--   rtable :: RemoteTable
--   rtable = registerStatic "$sdictSendPort" sdictSendPort
--          $ initRemoteTable
--     where
--       sdictSendPort :: SerializableDict ANY -&gt; SerializableDict (SendPort ANY)
--       sdictSendPort SerializableDict = SerializableDict
--   </pre>
--   
--   This definition of <tt>sdictSendPort</tt> ignores its argument
--   completely, and constructs a <tt>SerializableDict</tt> for the
--   <i>monomorphic</i> type <tt>SendPort ANY</tt>, which isn't what you
--   want. Instead, you should do
--   
--   <pre>
--   rtable :: RemoteTable
--   rtable = registerStatic "$sdictSendPort" (sdictSendPort :: SerializableDict ANY -&gt; SerializableDict (SendPort ANY))
--          $ initRemoteTable
--     where
--       sdictSendPort :: forall a. SerializableDict a -&gt; SerializableDict (SendPort a)
--       sdictSendPort SerializableDict = SerializableDict
--   </pre>
module Control.Distributed.Static

-- | A static value. Static is opaque; see <a>staticLabel</a> and
--   <a>staticApply</a>.
data Static a

-- | Create a primitive static value.
--   
--   It is the responsibility of the client code to make sure the
--   corresponding entry in the <a>RemoteTable</a> has the appropriate
--   type.
staticLabel :: String -> Static a

-- | Apply two static values
staticApply :: Static (a -> b) -> Static a -> Static b

-- | Construct a static value from a static pointer
--   
--   Since 0.3.4.0.
staticPtr :: forall a. Typeable a => StaticPtr a -> Static a

-- | Apply a static pointer to a static value
--   
--   Since 0.3.4.0.
staticApplyPtr :: (Typeable a, Typeable b) => StaticPtr (a -> b) -> Static a -> Static b

-- | Static version of (<a>.</a>)
staticCompose :: Static (b -> c) -> Static (a -> b) -> Static (a -> c)

-- | Static version of (<a>***</a>)
staticSplit :: Static (a -> b) -> Static (a' -> b') -> Static ((a, a') -> (b, b'))

-- | Static version of <a>const</a>
staticConst :: Static a -> Static (b -> a)

-- | Static version of <a>flip</a>
staticFlip :: Static (a -> b -> c) -> Static (b -> a -> c)

-- | A closure is a static value and an encoded environment
data Closure a
closure :: Static (ByteString -> a) -> ByteString -> Closure a

-- | Convert a static value into a closure.
staticClosure :: Static a -> Closure a

-- | Apply a static function to a closure
closureApplyStatic :: Static (a -> b) -> Closure a -> Closure b

-- | Closure application
closureApply :: forall a b. Closure (a -> b) -> Closure a -> Closure b

-- | Closure composition
closureCompose :: Closure (b -> c) -> Closure (a -> b) -> Closure (a -> c)

-- | Closure version of (<a>***</a>)
closureSplit :: Closure (a -> b) -> Closure (a' -> b') -> Closure ((a, a') -> (b, b'))

-- | Runtime dictionary for <a>unstatic</a> lookups
data RemoteTable

-- | Initial remote table
initRemoteTable :: RemoteTable

-- | Register a static label
registerStatic :: String -> Dynamic -> RemoteTable -> RemoteTable

-- | Resolve a static value
unstatic :: Typeable a => RemoteTable -> Static a -> Either String a

-- | Resolve a closure
unclosure :: Typeable a => RemoteTable -> Closure a -> Either String a
instance GHC.Show.Show (Control.Distributed.Static.Closure a)
instance GHC.Classes.Ord (Control.Distributed.Static.Closure a)
instance GHC.Classes.Eq (Control.Distributed.Static.Closure a)
instance GHC.Show.Show (Control.Distributed.Static.Static a)
instance GHC.Classes.Ord (Control.Distributed.Static.Static a)
instance GHC.Classes.Eq (Control.Distributed.Static.Static a)
instance GHC.Show.Show Control.Distributed.Static.StaticLabel
instance GHC.Classes.Ord Control.Distributed.Static.StaticLabel
instance GHC.Classes.Eq Control.Distributed.Static.StaticLabel
instance GHC.Show.Show Control.Distributed.Static.SDynamic
instance GHC.Classes.Eq Control.Distributed.Static.SDynamic
instance GHC.Classes.Ord Control.Distributed.Static.SDynamic
instance Control.DeepSeq.NFData Control.Distributed.Static.StaticLabel
instance Control.DeepSeq.NFData (Control.Distributed.Static.Static a)
instance Data.Typeable.Internal.Typeable a => Data.Binary.Class.Binary (Control.Distributed.Static.Static a)
instance Data.Typeable.Internal.Typeable a => Data.Binary.Class.Binary (Control.Distributed.Static.Closure a)
instance Control.DeepSeq.NFData (Control.Distributed.Static.Closure a)
