-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Serializable closures for distributed programming. -- -- See README. @package distributed-closure @version 0.4.2.0 -- | Private internals. You should not use this module unless you are -- determined to monkey with the internals. This module comes with no API -- stability guarantees whatsoever. Use at your own risks. module Control.Distributed.Closure.Internal -- | Values that can be sent across the network. type Serializable a = (Binary a, Typeable a) -- | Type of serializable closures. Abstractly speaking, a closure is a -- code reference paired together with an environment. A serializable -- closure includes a shareable code reference (i.e. a -- Closure). Closures can be serialized only if all expressions -- captured in the environment are serializable. data Closure a [StaticPtr] :: !StaticPtr a -> Closure a [Encoded] :: !ByteString -> Closure ByteString [Ap] :: !Closure (a -> b) -> !Closure a -> Closure b [Duplicate] :: Closure a -> Closure (Closure a) [Closure] :: a -> !Closure a -> Closure a -- | Lift a Static pointer to a closure with an empty environment. closure :: StaticPtr a -> Closure a -- | Resolve a Closure to the value that it represents. Calling -- unclosure multiple times on the same closure is efficient: for -- most argument values the result is memoized. unclosure :: Closure a -> a -- | A closure can be created from any serializable value. cpure -- corresponds to Control.Applicative's pure, but -- restricted to lifting serializable values only. cpure :: Closure (Dict (Serializable a)) -> a -> Closure a -- | Closure application. Note that Closure is not a functor, let -- alone an applicative functor, even if it too has a meaningful notion -- of application. cap :: Typeable a => Closure (a -> b) -> Closure a -> Closure b -- | Nested closure application. capDup :: Typeable a => Closure (Closure a -> b) -> Closure a -> Closure b -- | Closure is not a Functor, in that we cannot map -- arbitrary functions over it. That is, we cannot define fmap. -- However, we can map a static pointer to a function over a -- Closure. -- | Deprecated: Use staticMap instead. cmap :: Typeable a => StaticPtr (a -> b) -> Closure a -> Closure b -- | Turn a closure into a closure of a closure. cduplicate :: Closure a -> Closure (Closure a) instance GHC.StaticPtr.IsStatic Control.Distributed.Closure.Internal.Closure instance Data.Typeable.Internal.Typeable a => Data.Binary.Class.Binary (Control.Distributed.Closure.Internal.Closure a) -- | Serializable closures for distributed programming. This package builds -- a "remotable closure" abstraction on top of static pointers. -- See this blog post for a longer introduction. module Control.Distributed.Closure -- | Values that can be sent across the network. type Serializable a = (Binary a, Typeable a) -- | Type of serializable closures. Abstractly speaking, a closure is a -- code reference paired together with an environment. A serializable -- closure includes a shareable code reference (i.e. a -- Closure). Closures can be serialized only if all expressions -- captured in the environment are serializable. data Closure a -- | Lift a Static pointer to a closure with an empty environment. closure :: StaticPtr a -> Closure a -- | Resolve a Closure to the value that it represents. Calling -- unclosure multiple times on the same closure is efficient: for -- most argument values the result is memoized. unclosure :: Closure a -> a -- | A closure can be created from any serializable value. cpure -- corresponds to Control.Applicative's pure, but -- restricted to lifting serializable values only. cpure :: Closure (Dict (Serializable a)) -> a -> Closure a -- | Closure application. Note that Closure is not a functor, let -- alone an applicative functor, even if it too has a meaningful notion -- of application. cap :: Typeable a => Closure (a -> b) -> Closure a -> Closure b -- | Closure is not a Functor, in that we cannot map -- arbitrary functions over it. That is, we cannot define fmap. -- However, we can map a static pointer to a function over a -- Closure. -- | Deprecated: Use staticMap instead. cmap :: Typeable a => StaticPtr (a -> b) -> Closure a -> Closure b -- | Turn a closure into a closure of a closure. cduplicate :: Closure a -> Closure (Closure a) -- | A newtype-wrapper useful for defining instances of classes indexed by -- higher-kinded types. newtype WrappedArrowClosure a b WrapArrowClosure :: Closure (a -> b) -> WrappedArrowClosure a b [unwrapClosureArrow] :: WrappedArrowClosure a b -> Closure (a -> b) type (/->) = WrappedArrowClosure infixr 0 /-> -- | Values of type Dict p capture a dictionary for a -- constraint of type p. -- -- e.g. -- --
-- Dict :: Dict (Eq Int) ---- -- captures a dictionary that proves we have an: -- --
-- instance Eq 'Int ---- -- Pattern matching on the Dict constructor will bring this -- instance into scope. data Dict a [Dict] :: forall a. a => Dict a -- | It's often useful to create a static dictionary on-the-fly given any -- constraint. Morally, all type class constraints have associated static -- dictionaries, since these are either global values or simple -- combinations thereof. But GHC doesn't yet know how to invent a static -- dictionary on-demand yet given any type class constraint, so we'll -- have to do it manually for the time being. By defining instances of -- this type class manually, or via withStatic if it becomes too -- tedious. class c => Static c closureDict :: Static c => Closure (Dict c) instance (Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable b) => Data.Binary.Class.Binary (Control.Distributed.Closure.WrappedArrowClosure a b) instance (Control.Distributed.Closure.Static c1, Control.Distributed.Closure.Static c2, Data.Typeable.Internal.Typeable c1, Data.Typeable.Internal.Typeable c2, (c1, c2)) => Control.Distributed.Closure.Static (c1, c2) instance (Control.Distributed.Closure.Static c1, Control.Distributed.Closure.Static c2, Control.Distributed.Closure.Static c3, Data.Typeable.Internal.Typeable c1, Data.Typeable.Internal.Typeable c2, Data.Typeable.Internal.Typeable c3, (c1, c2, c3)) => Control.Distributed.Closure.Static (c1, c2, c3) instance (Control.Distributed.Closure.Static c1, Control.Distributed.Closure.Static c2, Control.Distributed.Closure.Static c3, Control.Distributed.Closure.Static c4, Data.Typeable.Internal.Typeable c1, Data.Typeable.Internal.Typeable c2, Data.Typeable.Internal.Typeable c3, Data.Typeable.Internal.Typeable c4, (c1, c2, c3, c4)) => Control.Distributed.Closure.Static (c1, c2, c3, c4) instance (Control.Distributed.Closure.Static c1, Control.Distributed.Closure.Static c2, Control.Distributed.Closure.Static c3, Control.Distributed.Closure.Static c4, Control.Distributed.Closure.Static c5, Data.Typeable.Internal.Typeable c1, Data.Typeable.Internal.Typeable c2, Data.Typeable.Internal.Typeable c3, Data.Typeable.Internal.Typeable c4, Data.Typeable.Internal.Typeable c5, (c1, c2, c3, c4, c5)) => Control.Distributed.Closure.Static (c1, c2, c3, c4, c5) instance (Control.Distributed.Closure.Static c1, Control.Distributed.Closure.Static c2, Control.Distributed.Closure.Static c3, Control.Distributed.Closure.Static c4, Control.Distributed.Closure.Static c5, Control.Distributed.Closure.Static c6, Data.Typeable.Internal.Typeable c1, Data.Typeable.Internal.Typeable c2, Data.Typeable.Internal.Typeable c3, Data.Typeable.Internal.Typeable c4, Data.Typeable.Internal.Typeable c5, Data.Typeable.Internal.Typeable c6, (c1, c2, c3, c4, c5, c6)) => Control.Distributed.Closure.Static (c1, c2, c3, c4, c5, c6) -- | Utility Template Haskell macros. module Control.Distributed.Closure.TH -- | $(cstatic 'foo) is an abbreviation for closure (static -- foo). cstatic :: Name -> ExpQ cstaticDict :: Name -> ExpQ -- | Abbreviation for closure (static Dict). Example usage: -- --
-- foo :: Closure (Dict (Num a)) -> ... -- -- foo $cdict ... --cdict :: ExpQ cdictFrom :: Natural -> ExpQ -- | Auto-generates the Static instances corresponding to the given -- class instances. Example: -- --
-- data T a = T a -- -- withStatic [d| instance Show a => Show (T a) where ... |] -- ======> -- instance Show a => Show (T a) where ... -- instance (Static (Show a), Typeable a) => Static (Show (T a)) where -- closureDict = closure (static (Dict -> Dict)) cap closureDict ---- -- You will probably want to enable FlexibleContexts and -- ScopedTypeVariables in modules that use withStatic. -- withStatic can also handle non-user generated instances like -- Typeable instances: just write instance Typeable T. withStatic :: DecsQ -> DecsQ -- | Closure is not a functor, since we cannot map arbitrary -- functions over it. But it sure looks like one, and an applicative one -- at that. What we can do is map static pointers to arbitrary -- functions over it (or in general, closures). Closure is not -- just an applicative functor, it's also a monad, as well as a comonad, -- if again we limit the function space to those functions that can be -- statically pointed to. -- -- In fact an entire hierarchy of classes mirroring the standard classes -- can be defined, where nearly the only difference lies in the fact that -- higher-order arguments must be a proof of static-ness (i.e. a -- Closure). The other difference is that composing static values -- requires a proof of typeability, so we carry those around -- (Typeable constraints). -- -- This module and others define just such a class hierarchy in the -- category of static functions (aka values of type Closure (a -- -> b)). module Data.Functor.Static -- | Instances of StaticFunctor should satisfy the following laws: -- --
-- staticMap (static id) = id -- staticMap (static (.) `cap` f `cap` g) = staticMap f . staticMap g --class Typeable f => StaticFunctor f staticMap :: (StaticFunctor f, Typeable a, Typeable b) => Closure (a -> b) -> f a -> f b instance Data.Functor.Static.StaticFunctor Control.Distributed.Closure.Internal.Closure module Control.Comonad.Static -- | Instances of StaticExtend should satisfy the following laws: -- --
-- staticExtend f = staticMap f . staticDuplicate -- staticDuplicate = staticExtend (static id) -- staticExtend f . staticExtend g = staticExtend (static (.) cap f cap staticExtend g) -- staticDuplicate . staticDuplicate = staticMap (static staticDuplicate) . staticDuplicate --class StaticFunctor w => StaticExtend w staticDuplicate :: (StaticExtend w, Typeable a) => w a -> w (w a) staticExtend :: (StaticExtend w, Typeable a, Typeable b) => Closure (w a -> b) -> w a -> w b class StaticExtend w => StaticComonad w staticExtract :: (StaticComonad w, Typeable a) => w a -> a instance Control.Comonad.Static.StaticComonad Control.Distributed.Closure.Internal.Closure instance Control.Comonad.Static.StaticExtend Control.Distributed.Closure.Internal.Closure module Control.Applicative.Static -- | Instances of StaticApply should satisfy the following laws -- (writing staticMap, staticApply as infix -- (<$>), (<*>), -- respectively): -- --
-- static (.) <$> u <*> v <*> w = u <*> (v <*> w) -- x <*> (f <$> y) = (static (flip (.)) `cap` f) <$> x <*> y -- f <$> (x <*> y) = (static (.) `cap` f) <$> x <*> y --class StaticFunctor f => StaticApply f staticApply :: (StaticApply f, Typeable a, Typeable b) => f (a -> b) -> f a -> f b class StaticApply f => StaticApplicative f staticPure :: (StaticApplicative f, Typeable a) => a -> f a instance Control.Applicative.Static.StaticApply Control.Distributed.Closure.Internal.Closure module Control.Monad.Static -- | Instances of StaticBind should satisfy the following laws -- (writing staticMap, staticApply, staticBind as -- infix (<$>), (<*>), -- (>>=), respectively): -- --
-- (m >>= f) >>= g = m >>= static (.) `cap` (staticFlippedBind g) cap f -- staticJoin . staticJoin = staticJoin . staticMap (static staticJoin) ---- -- where -- --
-- staticFlippedBind :: Closure (b -> m c) -> Closure (m b -> m c) -- staticFlippedBind = capDup (static (flip staticBind)) --class StaticApply m => StaticBind m staticBind :: (StaticBind m, Typeable a, Typeable b) => m a -> Closure (a -> m b) -> m b staticJoin :: (StaticBind m, Typeable a) => m (m a) -> m a class (StaticApplicative m, StaticBind m) => StaticMonad m staticReturn :: (StaticApplicative m, Typeable a) => a -> m a instance (Control.Applicative.Static.StaticApplicative m, Control.Monad.Static.StaticBind m) => Control.Monad.Static.StaticMonad m instance Control.Monad.Static.StaticBind Control.Distributed.Closure.Internal.Closure module Data.Profunctor.Static -- | Instances of StaticProfunctor should satisfy the following -- laws: -- --
-- staticDimap (static id) (static id) = static id -- staticLmap (static id) = static id -- staticRmap (static id) = static id -- staticDimap f g = staticLmap f . staticRmap g --class Typeable p => StaticProfunctor p staticDimap :: (StaticProfunctor p, Typeable a, Typeable b, Typeable c, Typeable d) => Closure (a -> b) -> Closure (c -> d) -> p b c -> p a d staticLmap :: (StaticProfunctor p, Typeable a, Typeable b, Typeable c) => Closure (a -> b) -> p b c -> p a c staticRmap :: (StaticProfunctor p, Typeable a, Typeable c, Typeable d) => Closure (c -> d) -> p a c -> p a d instance Data.Profunctor.Static.StaticProfunctor Control.Distributed.Closure.WrappedArrowClosure module Data.Profunctor.Choice.Static class StaticProfunctor p => StaticChoice p staticLeft' :: (StaticChoice p, Typeable a, Typeable b, Typeable c) => p a b -> p (Either a c) (Either b c) staticRight' :: (StaticChoice p, Typeable a, Typeable b, Typeable c) => p a b -> p (Either c a) (Either c b) instance Data.Profunctor.Choice.Static.StaticChoice Control.Distributed.Closure.WrappedArrowClosure module Data.Profunctor.Strong.Static class StaticProfunctor p => StaticStrong p staticFirst' :: (StaticStrong p, Typeable a, Typeable b, Typeable c) => p a b -> p (a, c) (b, c) staticSecond' :: (StaticStrong p, Typeable a, Typeable b, Typeable c) => p a b -> p (c, a) (c, b) instance Data.Profunctor.Strong.Static.StaticStrong Control.Distributed.Closure.WrappedArrowClosure