Changes between Version 1 and Version 2 of Architecture
- Timestamp:
- 01/14/10 00:46:24 (3 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Architecture
v1 v2 5 5 == The lowest layer: trampoline-style nestable coroutines == 6 6 7 This layer, implemented by the Control.Concurrent. Trampoline module, provides a limited coroutine functionality in Haskell. The centerpiece of the approach is the monad transformer Trampoline, that transforms an arbitrary monadic computation into a suspendable and resumable one. The basic definition is simple:7 This layer, implemented by the Control.Concurrent.Coroutine module, provides a limited coroutine functionality in Haskell. The centerpiece of the approach is the monad transformer Coroutine, that transforms an arbitrary monadic computation into a suspendable and resumable one. The basic definition is simple: 8 8 9 9 {{{ 10 newtype Trampoline s m r = Trampoline {bounce :: m (TrampolineState s m r)}10 newtype Coroutine s m r = Coroutine {resume :: m (CoroutineState s m r)} 11 11 12 data TrampolineState s m r = Done r | Suspend! (s (Trampoline s m r))12 data CoroutineState s m r = Done r | Suspend! (s (Coroutine s m r)) 13 13 14 instance (Functor s, Monad m) => Monad ( Trampoline s m) where15 return x = Trampoline (return (Done x))16 t >>= f = Trampoline (bounce t >>= apply f)17 where apply f (Done x) = bounce (f x)14 instance (Functor s, Monad m) => Monad (Coroutine s m) where 15 return x = Coroutine (return (Done x)) 16 t >>= f = Coroutine (resume t >>= apply f) 17 where apply f (Done x) = resume (f x) 18 18 apply f (Suspend s) = return (Suspend (fmap (>>= f) s)) 19 19 }}} 20 20 21 The Trampoline transformer type is parameterized by a functor. Here is an example of one functor particularly useful for a Trampoline computation:21 The Coroutine transformer type is parameterized by a functor. Here is an example of one functor particularly useful for a Coroutine computation: 22 22 23 23 {{{ … … 29 29 == Streams == 30 30 31 The next layer builds on the trampoline foundation to provide streaming computations. The main idea here is to introduce sinks and sources:31 The next layer builds on the coroutine foundation to provide streaming computations. The main idea here is to introduce sinks and sources: 32 32 33 33 {{{ 34 34 data Sink (m :: * -> *) a x = Sink { 35 put :: forall d. (AncestorFunctor a d) => x -> Trampoline d m Bool,36 canPut :: forall d. (AncestorFunctor a d) => Trampoline d m Bool35 put :: forall d. (AncestorFunctor a d) => x -> Coroutine d m Bool, 36 canPut :: forall d. (AncestorFunctor a d) => Coroutine d m Bool 37 37 } 38 38 39 39 newtype Source (m :: * -> *) a x = Source { 40 get :: forall d. (AncestorFunctor a d) => Trampoline d m (Maybe x)40 get :: forall d. (AncestorFunctor a d) => Coroutine d m (Maybe x) 41 41 } 42 42 }}} … … 46 46 {{{ 47 47 pipe :: forall m a a1 a2 x r1 r2. (Monad m, Functor a, a1 ~ SinkFunctor a x, a2 ~ SourceFunctor a x) => 48 (Sink m a1 x -> Trampoline a1 m r1) -> (Source m a2 x -> Trampoline a2 m r2) -> Trampoline a m (r1, r2)48 (Sink m a1 x -> Coroutine a1 m r1) -> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2) 49 49 }}} 50 50 … … 56 56 57 57 {{{ 58 type OpenConsumer m a d x r = AncestorFunctor a d => Source m a x -> Trampoline d m r59 type OpenProducer m a d x r = AncestorFunctor a d => Sink m a x -> Trampoline d m r58 type OpenConsumer m a d x r = AncestorFunctor a d => Source m a x -> Coroutine d m r 59 type OpenProducer m a d x r = AncestorFunctor a d => Sink m a x -> Coroutine d m r 60 60 type OpenTransducer m a1 a2 d x y = 61 (AncestorFunctor a1 d, AncestorFunctor a2 d) => Source m a1 x -> Sink m a2 y -> Trampoline d m [x]61 (AncestorFunctor a1 d, AncestorFunctor a2 d) => Source m a1 x -> Sink m a2 y -> Coroutine d m [x] 62 62 type OpenSplitter m a1 a2 a3 a4 d x b = 63 63 (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d, AncestorFunctor a4 d) => 64 Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Sink m a4 b -> Trampoline d m [x]64 Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Sink m a4 b -> Coroutine d m [x] 65 65 66 66 newtype Consumer m x r = Consumer {consume :: forall a d. OpenConsumer m a d x r}
