Fri Aug 26 13:02:04 CEST 2011
Are recursive signal processors applicative?
They are arrows. They do not seem to be monads due to structural
limitations; monads allow data-dependent computation structure while
recursive signal processors have a fixed structure. However, they
seem to be a generalization of monads that supports do notation when
the type of the computation is properly fixed.
data Signal a = forall s. Signal s (s -> (s, a))
they also do not seem to be applicative due to a data dependency
problem. It is possible to write an Applicative instance for the
above type, but it is not powerful enough to encode something
isomorphic to (s,i) -> (s,o)
instance Functor Signal => Applicative Signal where
pure v = Signal () $ \_ -> ((), v)
(<*>) (Signal sf f) (Signal sa a) = Signal (sf, sa) (signalApp f a)
signalApp :: (s1 -> (s1, (a -> b))) -> -- fi
(s2 -> (s2, a)) -> -- ai
(s1, s2) -> ((s1, s2), b) -- bi
signalApp fi ai = bi where
bi (s1, s2) = ((s1', s2'), b) where
(s1', f) = fi s1
(s2', a) = ai s2
b = f a
The type of Signal (i -> o) is isomorphic to:
s -> (s, (i -> o))
The state :: s cannot be influenced by the input :: i.
The type signature forbids any connection.
To give a more intuitive explanation of why this is impossible, think
about what happens when the recursion is unfolded. The resulting type
is [i->o]. Can the functions in that list still depend on each other?
The answer is a clear no. Those functions have to be pure. Suppose
the list is [f0,f1,..]. If f1 depended on the input of f0 it would
not be possible to evaluate f1 without evaluating f0 first. If they
are in a list there is no reason why we could not just ignore f0.
Funny how I still don't trust type signatures ;)
Side channels are always visible!