Etage-0.1.5: lib/Control/Etage/Propagate.hs
{-# LANGUAGE TypeFamilies, GADTs, ScopedTypeVariables, TypeSynonymInstances, DeriveDataTypeable, NamedFieldPuns #-}
module Control.Etage.Propagate (
propagate
) where
import Control.Monad
import Data.Typeable
import Control.Etage.Internals
import Control.Etage.Externals
-- TODO: Implement delay in propagation (constant delay, random from some distribution)
data PropagateNeuron from for = PropagateNeuron (PropagateOptions from for) deriving (Typeable)
type PropagateOptions from for = NeuronOptions (PropagateNeuron from for)
{-|
An internal 'Neuron' which implements 'propagate'.
-}
instance (Impulse from, Impulse for) => Neuron (PropagateNeuron from for) where
type NeuronFromImpulse (PropagateNeuron from for) = from
type NeuronForImpulse (PropagateNeuron from for) = for
data NeuronOptions (PropagateNeuron from for) = PropagateOptions {
for ::[TranslatableFor for]
}
mkDefaultOptions = return PropagateOptions {
for = undefined
}
grow options = return $ PropagateNeuron options
live nerve (PropagateNeuron PropagateOptions { for }) = forever $ do
i <- getForNeuron nerve
mapM_ (\(TranslatableFor n) -> translateAndSend n i) for
{-|
It 'grow's an internal 'Neuron' which 'propagate's 'Impulse's from a given 'Nerve' to other 'Nerve's, 'translate'-ing as necessary.
Check 'attachTo' for a more high-level function (of 'Incubation') taking care of all the details (like branching 'Nerve's as necessary).
Use this function only if you are dealing with 'grow'ing and 'attach'ing of 'Nerve's directly.
-}
propagate :: forall from for forConductivity. (Impulse from, Impulse for) => Nerve from AxonConductive for forConductivity -> [TranslatableFor from] -> IO ()
propagate _ [] = return ()
propagate from for = do
-- we do not manage this neuron, it will be cleaned by RTS at program exit
-- TODO: What if this is not the only thing the program is doing? Should we cleanup this threads at the end of Incubation, too?
_ <- attach (\o -> o { for } :: NeuronOptions (PropagateNeuron for from)) (cross from) -- we use cross here so that in neuron we can behave as in normal neuron (use getForNeuron for example)
return ()