Changes between Version 5 and Version 6 of Architecture
- Timestamp:
- 03/20/10 19:12:26 (3 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Architecture
v5 v6 7 7 The framework relies on the following packages: 8 8 * [wiki:monad-parallel monad-parallel] to enable parallel execution of monadic computations, and 9 * [wiki:monad-coroutine monad-coroutine] to enable the same monadic computations to suspend and resume each other.9 * [wiki:monad-coroutine monad-coroutine] for the ability to suspend and resume monadic computations. 10 10 11 11 == Streams == 12 12 13 The lowest layer builds on the coroutine foundation to provide streaming computations. The main idea here is to introduce sinks and sources:13 The lowest layer builds on the monad-coroutine foundation to provide streaming computations. The main idea here is to introduce sinks and sources: 14 14 15 15 {{{ 16 16 data Sink (m :: * -> *) a x = Sink { 17 put :: forall d. (AncestorFunctor a d) => x -> Coroutine d m Bool, 18 canPut :: forall d. (AncestorFunctor a d) => Coroutine d m Bool 17 put :: forall d. (AncestorFunctor a d) => x -> Coroutine d m () 19 18 } 20 19 … … 31 30 }}} 32 31 33 This function takes two coroutines as arguments, ''producer'' and ''consumer''. The producer gets a sink argument, and the consumer a source argument. All data that the producer writes to the sink can be read from the source by the consumer. The arrangement couldn't be simpler. Here is a contrived example of a producer/consumer pair:32 This function takes two coroutines as arguments, ''producer'' and ''consumer''. The producer takes a sink argument, and the consumer a source argument. All data that the producer writes to the sink can be read from the source by the consumer. The arrangement couldn't be simpler. Here is a contrived example of a producer/consumer pair: 34 33 35 34 {{{ … … 47 46 }}} 48 47 49 The {{{rangeProducer}}} coroutine produces a range of integers while the {{{sumConsumer}}} consumes all the numbers and sums them up. The two coroutines are bound together by {{{pipe}}}. Note that either of them could be bound to a different coroutine and still perform its job. Furthermore, though in this example both coroutines run in the IO monad, they are completely generic and could run in any monad.48 The {{{rangeProducer}}} coroutine produces a range of integers while the {{{sumConsumer}}} consumes all the numbers and sums them up. The two coroutines are bound together by {{{pipe}}}. Note that either of them could be replaced by a different coroutine of the same type and the other coroutine would still perform its job. Furthermore, though in this example both coroutines run in the IO monad, they are completely generic and could run in any monad. 50 49 51 50 == Components and combinators == … … 56 55 type OpenConsumer m a d x r = AncestorFunctor a d => Source m a x -> Coroutine d m r 57 56 type OpenProducer m a d x r = AncestorFunctor a d => Sink m a x -> Coroutine d m r 58 type OpenTransducer m a1 a2 d x y =59 (AncestorFunctor a1 d, AncestorFunctor a2 d) => Source m a1 x -> Sink m a2 y -> Coroutine d m [x]60 type OpenSplitter m a1 a2 a3 a4 d x b =57 type OpenTransducer m a1 a2 d x y r = 58 (AncestorFunctor a1 d, AncestorFunctor a2 d) => Source m a1 x -> Sink m a2 y -> Coroutine d m r 59 type OpenSplitter m a1 a2 a3 a4 d x b r = 61 60 (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d, AncestorFunctor a4 d) => 62 Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Sink m a4 b -> Coroutine d m [x]61 Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Sink m a4 b -> Coroutine d m r 63 62 64 63 newtype Consumer m x r = Consumer {consume :: forall a d. OpenConsumer m a d x r} 65 64 newtype Producer m x r = Producer {produce :: forall a d. OpenProducer m a d x r} 66 newtype Transducer m x y = Transducer {transduce :: forall a1 a2 d. OpenTransducer m a1 a2 d x y }67 newtype Splitter m x b = Splitter {split :: forall a1 a2 a3 a4 d. OpenSplitter m a1 a2 a3 a4 d x b }65 newtype Transducer m x y = Transducer {transduce :: forall a1 a2 d. OpenTransducer m a1 a2 d x y ()} 66 newtype Splitter m x b = Splitter {split :: forall a1 a2 a3 a4 d. OpenSplitter m a1 a2 a3 a4 d x b ()} 68 67 }}} 69 68
