On Fri, Sep 14, 2012 at 12:45 PM, Florian Lorenzen wrote:<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I&#39;d like to transform a value of an ADT to a GADT. Suppose I have the<br>
simple expression language<br>
<br>
&gt; data Exp = Lit Int &gt; | Succ Exp &gt; | IsZero Exp &gt; | If Exp Exp Exp<br>
<br>
and the GADT<br>
<br>
&gt; data Term t where &gt; TLit :: Int -&gt; Term Int &gt; TSucc :: Term Int -&gt;<br>
Term Int &gt; TIsZero :: Term Int -&gt; Term Bool &gt; TIf :: Term Bool -&gt; Term<br>
ty -&gt; Term ty -&gt; Term ty<br>
<br>
that encodes the typing rules.<br>
<br>
Now, I&#39;d like to have a function<br>
<br>
&gt; typecheck :: Exp -&gt; Maybe (Term t) &gt; typecheck exp = &lt;...&gt;<br>
<br>
that returns the GADT value corresponding to `exp&#39; if `exp&#39; is type<br>
correct.<br></blockquote><div><br></div><div>It&#39;s not pretty, but it should still be safe...</div><div><br></div><div><div><font face="courier new, monospace">import Control.Applicative</font></div><div><font face="courier new, monospace">import Unsafe.Coerce</font></div>


<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">tcInt :: Exp -&gt; Maybe (Term Int)</font></div><div><font face="courier new, monospace">tcInt (Lit i)       = pure (TLit i)</font></div>


<div><font face="courier new, monospace">tcInt (Succ e)      = TSucc &lt;$&gt; tcInt e</font></div><div><font face="courier new, monospace">tcInt (If c e1 e2)  = TIf &lt;$&gt; tcBool c &lt;*&gt; tcInt e1 &lt;*&gt; tcInt e2</font></div>


<div><font face="courier new, monospace">tcInt _             = empty</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">tcBool :: Exp -&gt; Maybe (Term Bool)</font></div>


<div><font face="courier new, monospace">tcBool (IsZero e)   = TIsZero &lt;$&gt; tcInt e</font></div><div><font face="courier new, monospace">tcBool (If c e1 e2) = TIf &lt;$&gt; tcBool c &lt;*&gt; tcBool e1 &lt;*&gt; tcBool e2</font></div>


<div><font face="courier new, monospace">tcBool _            = empty</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">typecheck :: Exp -&gt; Maybe (Term t)</font></div>


<div><font face="courier new, monospace">typecheck e = forget &lt;$&gt; tcInt e &lt;|&gt; forget &lt;$&gt; tcBool e</font></div><div><font face="courier new, monospace">  where</font></div><div><font face="courier new, monospace">    forget :: Term a -&gt; Term b</font></div>


<div><font face="courier new, monospace">    forget = unsafeCoerce</font></div></div><div><br></div><div>Regards,</div><div>Sean</div></div>