packages feed

Etage 0.1 → 0.1.1

raw patch · 3 files changed

+19/−25 lines, 3 files

Files

Etage.cabal view
@@ -1,8 +1,8 @@ Name:                Etage-Version:             0.1+Version:             0.1.1 Synopsis:            A general data-flow framework-Description:         A general data-flow framework featuring nondeterminism and neurological pseudo-terminology. It can be used for-                     example for data-flow computations or event propagation networks. It tries hard to aide type checking and to+Description:         A general data-flow framework featuring nondeterminism, laziness and neurological pseudo-terminology. It can be+                     used for example for data-flow computations or event propagation networks. It tries hard to aide type checking and to                      allow proper initialization and cleanup so that interfaces to input and output devices (data or events producers or                      consumers) can be made (so that created models\/systems\/networks can be used directly in real world applications, for                      example robots).
lib/Control/Etage/Function.hs view
@@ -1,8 +1,9 @@ {-# LANGUAGE TypeFamilies, MultiParamTypeClasses, GADTs, FlexibleInstances, ScopedTypeVariables, DeriveDataTypeable, TypeSynonymInstances, NamedFieldPuns, BangPatterns #-}  {-|-This module defines a 'Neuron' which sends results of applying a given function to recieved 'Impulse's. You 'grow' it in-'Incubation' by using something like:+This module defines a 'Neuron' which applies a given function to received 'Impulse's. As Haskell is a lazy language this does+not mean that the result will be immediately evaluated but that it will be evaluated when (and if) the result will be needed+(probably in some other 'Neuron'). You 'grow' it in 'Incubation' by using something like:  > nerveFunction <- growNeuron (\o -> o { function = negate . sum }) :: NerveBoth FunctionNeuron @@ -21,7 +22,6 @@  import Control.Applicative import Control.Monad-import Data.Time.Clock import Data.Typeable  import Control.Etage@@ -37,9 +37,8 @@ {-| 'Impulse's from 'FunctionNeuron'. This 'Impulse' constructor is defined: -[@Value { impulseTimestamp :: 'ImpulseTime', value :: 'Rational', evaluationTime :: 'NominalDiffTime' }@]-@impulseTimestamp@ is time when the result was evaluated, @value@ contains the evaluated result, @evaluationTime@ is how long the-evaluation took.+[@Value { impulseTimestamp :: 'ImpulseTime', value :: 'Rational' }@]+@impulseTimestamp@ is time when the function was applied (but not when the result was evaluated), @value@ contains the (lazy) result. -} type FunctionFromImpulse = NeuronFromImpulse FunctionNeuron -- | 'Impulse's for 'FunctionNeuron'. This 'Neuron' can recieve any 'Impulse' type.@@ -70,12 +69,11 @@ instance Ord FunctionForImpulse where   compare = impulseCompare --- | A 'Neuron' which sends results of a given function for recieved 'Impulse's.+-- | A 'Neuron' which applies a given function to received 'Impulse's. instance Neuron FunctionNeuron where   data NeuronFromImpulse FunctionNeuron = Value {       impulseTimestamp :: ImpulseTime, -- time is first so that ordering is first by time-      value :: Rational,-      evaluationTime :: NominalDiffTime+      value :: Rational     } deriving (Eq, Ord, Read, Show)   data NeuronForImpulse FunctionNeuron where     FunctionForImpulse :: Impulse i => i -> FunctionForImpulse@@ -91,10 +89,9 @@      live nerve (FunctionNeuron FunctionOptions { function }) = forever $ do     i <- head <$> waitAndSlurpForNeuron nerve -- just newest-    time1 <- getCurrentImpulseTime-    let !r = function . impulseValue $ i-    time2 <- getCurrentImpulseTime-    sendFromNeuron nerve Value { impulseTimestamp = time2, value = r, evaluationTime = time2 - time1 }+    let r = function . impulseValue $ i+    time <- getCurrentImpulseTime+    sendFromNeuron nerve Value { impulseTimestamp = time, value = r }  instance Impulse i => ImpulseTranslator i FunctionForImpulse where   translate i = [FunctionForImpulse i]
lib/Control/Etage/Internals.hs view
@@ -41,18 +41,15 @@ 'Neuron's which operate on any 'Impulse' type. An example of such 'Neuron' is "Control.Etage.Function". -} class (Show i, Typeable i) => Impulse i where-  -- | This method should return a timestamp when the 'Impulse' was created/finalized what should be the moment just before it is send over-  -- the 'Nerve'. So the moment it formed into its final form and started leaving the 'Neuron'.+  -- | This method should return a timestamp when the 'Impulse' was created/finalized what should be the moment just before it is send+  -- over the 'Nerve', the moment it formed into its final form and started leaving the 'Neuron'. As Haskell is a lazy language this+  -- does not mean that at that moment all values the 'Impulse' defines are really already evaluated (they are evaluated when they are+  -- needed, probably in some other 'Neuron').   ---  -- Be careful that Haskell is a lazy language so such code:+  -- You can do something like:   ---  -- > let v = lengthlyComputation   -- > time <- getCurrentImpulseTime-  -- > sendFromNeuron nerve Value { impulseTimestamp = time, value = v }-  ---  -- will evaluate @v@ after 'getCurrentImpulseTime' call. You should make @v@ strict (using @BangPatterns@) like:-  ---  -- > let !v = lengthlyComputation+  -- > sendFromNeuron nerve YourImpulse { impulseTimestamp = time, ... }   impulseTime :: i -> ImpulseTime   -- | This method should return all values (data payload) the 'Impulse' defines. Currently order and format is not yet finalized so   -- it is just a list of 'Rational' values in some order (for now it probably should be the order in which the values are defined