 WARNING: In stateful monads, e.g. m = IO, this *can* side-effect the System.
-- That's by design. 
runInteractT :: (Monad m, Ord i) => InteractT i u c s m a -> System i m s c -> u -> m (a, u)
runInteractT intx system st =
   case intx of
     Terminal a -> return (a, st)
     Talk send cont ->
       sync system send >>= (\(intx1, sys1) -> runInteractT (cont intx1) sys1 st)
     Stateful cont ->
       let (intx1, st1) = cont st in runInteractT intx1 system st1
     M cont ->
       cont >>= (\intx1 -> runInteractT intx1 system st)


runInteractT :: (Monad m, Ord i) => InteractT i u c s m a -> System i m s c -> u -> m (a, u)
runInteractT intx system st =
   case intx of
     Terminal a -> return (a, st)
     Talk send cont ->
       sync system send >>= (\(intx1, sys1) -> runInteractT (cont intx1) sys1 st)
     Stateful cont ->
       let (intx1, st1) = cont st in runInteractT intx1 system st1
     M cont ->
       cont >>= (\intx1 -> runInteractT intx1 system st)
runInteractT intx system st =
   case intx of
     Terminal a -> return (a, st)
     Talk send cont ->
       sync system send >>= (\(intx1, sys1) -> runInteractT (cont intx1) sys1 st)
     Stateful cont ->
       let (intx1, st1) = cont st in runInteractT intx1 system st1
     M cont ->
       cont >>= (\intx1 -> runInteractT intx1 system st)