<div dir="ltr"><div class="gmail_extra"><div>I'm not sure if this answers your questions, but I think this particular problem has a cleaner solution with GADTs:</div><div><br></div><div> {-# LANGUAGE GADTs #-}</div>
<div> </div><div> data Cmd s t where</div><div> Push :: a -> Cmd s (a,s)</div><div> F1 :: (a -> b) -> Cmd (a,s) (b,s)</div><div> F2 :: (a -> b -> c) -> Cmd (a,(b,s)) (c,s)</div>
<div> </div><div> data Prog s t where</div><div> (:.) :: Cmd s t -> Prog t u -> Prog s u</div><div> End :: Prog s s</div><div> </div><div> infixr 5 :.</div><div> </div><div> cmd :: Cmd s t -> s -> t</div>
<div> cmd (Push a) s = (a, s)</div><div> cmd (F1 f) (a,s) = (f a, s)</div><div> cmd (F2 f) (a,(b,s)) = (f a b, s)</div><div> </div><div> prog :: Prog s t -> s -> t</div><div> prog (c :. p) s = prog p (cmd c s)</div>
<div> prog End s = s</div><div> </div><div> run :: Prog () t -> t</div><div> run p = prog p ()</div><div><br></div><div>Then from GHCi:</div><div> </div><div> > run (Push 3 :. Push 4 :. F2 (+) :. F1 show :. End)</div>
<div> ("7",())</div><div><br></div><div>Maybe you really want GADTs? :)</div><div><br></div><div>-Eric</div></div></div>