
That's a great point, thanks. I'll have to remember to interrogate
myself on that next time I find myself reaching for this pattern. I wonder if your version can be made to work for functions of any arity?
Since functions get their arguments from the stack in reverse order, this implementation actually already supports functions of any arity if you just follow it with an appropriate number of `F2 ($)` commands. First, here's a nicer eval function: eval :: Prog () (a,()) eval p = fst (prog p ()) And here's how to apply the 3-ary function `zipWith` and the 4-ary function `zipWith3`: > eval (Push [1..3] :. Push [4..6] :. Push (,) :. F2 zipWith :. F2 ($) :. End) [(4,1),(5,2),(6,3)] > eval (Push [1..3] :. Push [4..6] :. Push [7..9] :. Push (,,) :. F2 zipWith3 :. F2 ($) :. F2 ($) :. End) [(7,4,1),(8,5,2),(9,6,3)] -Eric