Tue Jul 21 20:58:12 EDT 2015

The problem is not the Arrow instance

-- Simplification of Sys.

-- A state space model maps state and input to state and output.
-- The monad is needed for code generation.
type Siso m s i o = (s,i) -> m (s,o)

-- Represent a system as initial value + update function.
-- State is anstract to allow this to fit the Category / Arrow instances.
-- Observe that this is roughly equivalent to [i] -> m [o]  (s eliminated).
data Sys m i o = forall s. (GenVal s) => Sys s (Siso m s i o)

-- Value generation stub. This is for being able to generate values to
-- feed the state machine.
class GenVal s where
  genVal :: s
instance (GenVal s1, GenVal s2) => GenVal (s1,s2) where
  genVal = (genVal, genVal)         
instance GenVal () where
  genVal = ()
instance Monad m => Category (Sys m) where
  id = Sys () (\((), i) -> return ((), i))
  (Sys sg g) . (Sys sf f) =
    Sys (sg, sf) (\((sg, sf), i) -> do
                     (sf', x) <- f (sf, i)
                     (sg', o) <- g (sg, x)
                     return ((sg', sf'), o))

instance Monad m => Arrow (Sys m) where
  arr f = Sys () (\((),i) -> return ((), f i))
  first (Sys sf f) =
    Sys sf (\(sf, (i,x)) -> do
               (sf', o) <- f (sf, i)
               return (sf', (o,x)))