On Mon, Jun 11, 2012 at 9:58 PM, AntC <span dir="ltr">&lt;<a href="mailto:anthony_clayden@clear.net.nz" target="_blank">anthony_clayden@clear.net.nz</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">Simon Peyton-Jones &lt;simonpj &lt;at&gt; <a href="http://microsoft.com" target="_blank">microsoft.com</a>&gt; writes:<br>
<br>
&gt;<br>
&gt; There is a little, ill-documented, sub-kind hierarchy in GHC.  I&#39;m trying<br>
hard to get rid of it as much as<br>
&gt; possible, and it is much less important than it used to be. It&#39;s always been<br>
there, and is nothing to do with polykinds.<br>
&gt;<br>
&gt; I&#39;ve extended the commentary a bit: see &quot;Types&quot; and &quot;Kinds&quot; here<br>
&gt; <a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler" target="_blank">http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler</a><br>
&gt;<br>
&gt; The ArgKind thing has gone away following Max&#39;s recent unboxed-tuples patch,<br>
so we now only have OpenKind<br>
&gt; (described on the above pages).<br>
<br>
</div>Thank you Simon, Richard, ~d, et al (so much kindness to a stranger!)<br>
<br>
It&#39;s not that I have a specific problem (requirement) I&#39;m trying to solve.<br>
It&#39;s more that I&#39;m trying to understand how this ladder of<br>
Sorts/Kinds/Types/values hangs together.<br>
<br>
With Phantom types, we&#39;ve been familiar for many years with uninhabited types,<br>
so why are user-defined (promoted) Kinds/Types different?<br>
<br>
The Singletons stuff shows there are use cases for mapping from uninhabited<br>
types to values -- but it seems to need a lot of machinery (all those shadow<br>
types and values). And indeed TypeRep maps from not-necessarily-inhabited<br>
types to values.<br>
<br>
Is it that we really need to implement type application in the surface<br>
language to get it all to come together? Then we won&#39;t need functions applying<br>
to dummy arguments whose only purpose is to carry a Type::Kind.<br>
<br>
To give a tight example:<br>
<br>
    data MyNat = Z | S MyNat                -- to be promoted<br>
<br>
    data ProxyNat (a :: MyNat) = ProxyNat   -- :k ProxyNat :: MyNat -&gt; *<br>
<br>
    proxyNat :: n -&gt; ProxyNat n             -- rejected: Kind mis-match<br>
    proxyNat _ = ProxyNat<br>
<br>
The parallel of that with phantom types (and a class constraint for MyNat)<br>
seems unproblematic -- albeit with Kind *.<br>
<br>
Could we have :k (-&gt;) :: OpenKind -&gt; * -&gt; *  -- why not?</blockquote><div><br></div><div><div>I don&#39;t quite understand why you would want arbitrary kinded arguments, but only in negative position. </div></div>
<div><br></div><div>Internally its already more like (-&gt;) :: OpenKind -&gt; OpenKind -&gt; * at the moment. The changes simply permitted unboxed tuples in argument position, relaxing a previous restriction. OpenKind is just a superkind of * and #, not every kind. Kinds other than * and # just don&#39;t have a term level representation. (Well kind Constraint is inhabited by dictionaries for instances after a fashion, but you don&#39;t get to manipulate them directly.)</div>
<div><br></div><div>I&#39;m a lot happier with the new plumbing than I was with the crap I&#39;ve been able to write by hand over the years for natural number types/singletons, and I&#39;m actually pretty happy with the fact that it makes it clearer that there is a distinction between the type level and the term level, and I can&#39;t say that I buy the idea of just throwing things open like that.</div>
<div><br></div><div>In particular, the &quot;OpenKind&quot; for all kinds that you seem to be proposing sounds more like letting (-&gt;) :: forall (a :: BOX?) (b :: BOX?). a -&gt; b -&gt; * (or (-&gt;) :: forall (a :: BOX?). a -&gt; * -&gt; *) than OpenKind, which exists to track where unboxed types can lurk until polymorphism forces it to *.</div>
<div><br></div><div>With the &#39;more open&#39; OpenKind you propose, it no longer collapses to * when used in a polymorphic fashion, but merely dumbs down to forall (a :: BOX). a, which strikes me as a particularly awkward transition. At the least, you&#39;d need to actually break the &#39;BOX is the only superkind&#39; rule to provide the quantification that can span over unboxed types and any boxed type, (scribbled as BOX? above). </div>
<div><br></div><div>That seems to be a pretty big mess for something that can be solved readily with simpler tools.</div><div><br></div><div>Mind you there is another case for breaking the BOX is the only superkind rule (that is the horrible syntax hack that requires monomorphization of the kinds of the results of type/data families can be cleaned up), but once you have more than one superkind, you start complicating type equality, needing other coercions, so it really shouldn&#39;t be done lightly.</div>
<div><br></div><div>-Edward</div></div>