{-# LANGUAGE FlexibleContexts, UndecidableInstances, ExistentialQuantification #-} import Control.Applicative -- Attempt to write a state space model implementation in terms of a -- higher order Signal implementation that can implement Applicative. 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 -- Need existential quantification for s to hide the "growing" state -- parameter each time signalApp is applied. data Signal a = forall s. Signal s (s -> (s, a)) instance Functor Signal => Applicative Signal where pure v = Signal () $ \_ -> ((), v) (<*>) (Signal sf f) (Signal sa a) = Signal (sf, sa) (signalApp f a) instance Functor Signal where fmap f a = (pure f) <*> a -- Construct a signal from an infinite list. Note that this creates a -- "virtual" signal that's only useful as a test since the initial -- state is not serializable. fromSeq s = Signal s pop where pop (s:ss) = (ss, s) dirac :: (Enum n, Num n) => Signal n dirac = fromSeq (1:[0,0..]) -- Printing Signal instances is done by converting them to lists. toSeq (Signal init tick) = f init where f s = (v : f s') where (s', v) = tick s instance Show a => Show (Signal a) where show = show . (take 10) . toSeq instance (Eq (Signal a), Num a) => Num (Signal a) where (+) = liftA2 (+) (*) = liftA2 (*) abs = fmap abs signum = fmap signum fromInteger = pure . fromInteger ni = error "NI" instance Eq (Signal a) where (==) = ni {- currySSM :: ((s,i) -> (s,o)) -> (s -> i -> (s, o)) currySSM ssm = f where f s i = (s', o) where (s', o) = ssm (s, i) -}