<div dir="ltr">Incidentally I did find a solution that fits into the type system and also produces the correct result. This was done by making the global parameter change type as well at each lambda so that it becomes a function with the same arrity as the term. Unfortunately to evaluate these terms the program needs fork and do redundant work at every application of lam (so it&#39;s a major hack), though it does give me some confidence that a real solution is possible perhaps by using dependent types?:<div>
----</div><div><div>lam :: ((g-&gt;(g,a)) -&gt; (g-&gt;(g&#39;,b))) -&gt; (g-&gt;(a-&gt;g&#39;,a-&gt;b))</div><div>lam = (\ f -&gt; \ g -&gt; (\x -&gt; fst $ (f (\ gv-&gt;(gv,x))) g, </div><div>                      \y -&gt; snd $ (f (\ gv-&gt;(gv,y))) g ))</div>
<div><br></div><div>app :: (g-&gt;(a-&gt;g1,a-&gt;b)) -&gt; (g-&gt;(g,a)) -&gt; (g-&gt;(g1,b))</div><div>app = (\ eA eB -&gt; \ gz -&gt; let    (gB, fB) = eB gz</div><div>                          in let (lgA, lfA) = eA gB</div>
<div>                          in     (lgA fB, lfA fB) )</div><div>                          </div><div>ext :: ((g1,a)-&gt;(g2,b))-&gt;(g0-&gt;(g1,a))-&gt;(g0-&gt;(g2,b))                     </div><div>ext = \f -&gt; \a -&gt; \g -&gt; f (a g)</div>
<div><br></div><div>idCounter :: Num g =&gt; (g,a) -&gt; (g, a)</div><div>idCounter = \(g, x) -&gt; (g+1, x)</div><div><br></div><div>-- Example terms</div><div>trmA = lam (\x -&gt; lam (\y -&gt; app x y))</div><div>trmB = (lam (\y -&gt; app trmC y))</div>
<div>trmC = (\g -&gt; (\c-&gt;g,\c-&gt;c+3))</div><div>trmD = (\g -&gt; (g,3))</div><div>trmE = app trmC trmD</div><div>trmF = (ext idCounter) trmD</div><div>trmG = app trmC (app trmC trmF)</div><div>trmH = app trmC trmE</div>
</div><div><br></div><div>---</div><div><br></div><div>Here&#39;s my original statement of the problem <a href="http://hastebin.com/raw/bewiqihiyo">http://hastebin.com/raw/bewiqihiyo</a></div><div>And here&#39;s all my code with new, <a href="http://hpaste.org/86273">http://hpaste.org/86273</a></div>
<div><br></div><div>Unfortunately, I don&#39;t know of a way to tell the compiler that essentially the variables x and y in the lam function will always be applied to the same value. Unfortunately, I&#39;ve reached a limit of my understanding of how pairs integrate with the type system in Haskell,</div>
<div>I&#39;ve considered returning something other than a pair from my base function (such as a function) but I have yet to figure that out.</div><div><br></div><div>Thanks for your insights,</div><div>Ian Bloom</div></div>