I find it easy to understand this distinction by writing out the types of the constructors and case expressions for these objects, in a language like system F:<br><br>(here, {x :: t} means a type argument with name x of kind t)<br>
<br>Exists :: {f :: *-&gt;*} -&gt; {a :: *} -&gt; f a -&gt; Exists f<br>Forall :: {f :: *-&gt;*} -&gt; ({a :: *} -&gt; f a) -&gt; Forall f<br><br>Notice the higher rank type in the constructor &#39;Forall&#39;.<br><br>Similarly, the case deconstruction for these:<br>
<br>caseExists :: {r :: *} -&gt; {f :: *-&gt;*} -&gt; ({a :: *} -&gt; f a -&gt; r) -&gt; Exists f -&gt; r<br>caseForall :: {r :: *} -&gt; {f :: *-&gt;*} -&gt; (({a :: *} -&gt; f a) -&gt; r) -&gt; Forall f -&gt; r<br><br>The function passed to caseExists needs to be able to handle any type &#39;a&#39; we throw at it, whereas the function passed to caseForall can choose what &#39;a&#39; it wants to use (and can choose multiple different &#39;a&#39;s by calling the ({a::*} -&gt; f a) parameter function multiple times.  In the simple case that the case function only instantiates &#39;a&#39; at a single type, we can simplify this:<br>
<br>caseForall&#39; :: {r :: *} -&gt; {f :: * -&gt; *} -&gt; {a :: *} -&gt; (f a -&gt; r) -&gt; Forall f -&gt; r<br><br>and this function is definable in terms of caseForall:<br><br>caseForall&#39; {r} {f} {a} k v = caseForall {r} {f} (\mk_fa -&gt; k (mk_fa {a})) v<br>
<br>  -- ryan<br><br><div class="gmail_quote">On Mon, Mar 5, 2012 at 9:37 PM, wren ng thornton <span dir="ltr">&lt;<a href="mailto:wren@freegeek.org">wren@freegeek.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 3/5/12 5:13 PM, AntC wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
I&#39;ve tried that ListFunc wrapping you suggest:<br></div>
[...]<div class="im"><br>
But I can&#39;t &#39;dig out&#39; the H-R function and apply it (not even<br>
monomorphically):<br>
</div></blockquote>
<br>
That&#39;s because the suggestion changed it from a universal quantifier to an existential quantifier.<br>
<br>
    data Exists f = forall a. Exists (f a)<br>
<br>
    data Forall f = Forall (forall a. f a)<br>
<br>
With Exists, we&#39;re essentially storing a pair of the actual type &#39;a&#39; and then the f a itself. We can&#39;t just pull out the f a and use it, because we don&#39;t know what &#39;a&#39; is. We can bring it into scope temporarily by case matching on the Exists f, which allows us to use polymorphic functions, but we still don&#39;t actually know what it is so we can *only* use polymorphic functions.<br>

<br>
Conversely, with Forall we&#39;re storing some f a value which is in fact polymorphic in &#39;a&#39;. Here, because it&#39;s polymorphic, the caller is free to choose what value of &#39;a&#39; they would like the f a to use. Indeed, they can choose multiple different values of &#39;a&#39; and get an f a for each of them.<span class="HOEnZb"><font color="#888888"><br>

<br>
-- <br>
Live well,<br>
~wren</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
______________________________<u></u>_________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br>