On 3/19/07, <b class="gmail_sendername">Lennart Augustsson</b> &lt;<a href="mailto:lennart@augustsson.net" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">lennart@augustsson.net</a>&gt; wrote:<div><span class="gmail_quote">
</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Ravi,<br><br>Ganesh and I were discussing today what would happen if one adds Id<br>as a primitive type constructor.&nbsp;&nbsp;How much did you have to change the<br>type checker?&nbsp;&nbsp;</blockquote><div><br>All I did is add an expansion rule for my Id constructor to the place where the SizeOf pseudo-constructor was expanded. This basically means that if the typechecker sees Id applied so something, it is simplified out (as part of type-normalization / synonym expansion).
<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Presumably if you need to unify &#39;m a&#39; with &#39;a&#39; you now<br>have to set m=Id.&nbsp;&nbsp;Do you know if you can run into higher order
<br>unification problems?&nbsp;&nbsp;My gut feeling is that with just Id, you<br>probably don&#39;t, but I would not bet on it.</blockquote><div><br>I didn&#39;t change the unification rules, so &#39;m a&#39;, would NOT unify with &#39;a&#39; with m=Id. That was mainly because I didn&#39;t need that unification rule to handle the case where I used the Id constructor.
<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Having Id would be cool.&nbsp;&nbsp;If we make an instance &#39;Monad Id&#39; it&#39;s now
<br>possible to get rid of map and always use mapM instead.&nbsp;&nbsp;Similarly<br>with other monadic functions.<br>Did you do that in the Bluespec compiler?</blockquote><div><br>I did experiment with Monad Id while trying to sort something else out, and it seemed to work (the instance typechecked as well as some code that depended on that instance), but I didn&#39;t push it very hard.
<br><br>Beyond that, in response to your note, I tried to see what would happen if I added a unification rule for &#39;m a&#39; with &#39;a&#39;, with m=Id. There turned out to be three important details (to keep existing Bluespec code working):
<br>&nbsp;- make sure to choose to unify &#39;m a&#39; with a separate type variable &#39;b&#39; directly, in preference to setting m=Id and unifying a with b. Upon reflection, that seemed reasonable because it didn&#39;t prevent setting m=Id later, in response to additional information.
<br>&nbsp;- make sure not to replace m with Id, if m is a lexically-bound type variable<br>&nbsp;- make sure to expand type synonyms before attempting this sort of unification<br><br>After that I could typecheck simple things like the following (using an inferred identity monad):
<br><br>x :: Integer<br>x = return 5<br><br>y :: List Integer<br>y = mapM (const 5) (cons 1 (cons 2 nil))<br><br>However, I did run into the problems Iavor and Simon mentioned. For example, the following program did not typecheck:
<br><br>z :: Bool -&gt; Maybe (Integer)<br>z p1 = let f a0 b0 =<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let a = return a0<br>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b = return b0<br>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in if p1 then a else b<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in f 5 (Just 6)<br><br>
However, the same could *would* typecheck if I added the following type annotations:<br><br>z :: Bool -&gt; Maybe (Integer)<br>
z p1 = let f a0 b0 =<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let a = return (a0 :: Integer)<br>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b = return (b0 :: Maybe Integer)<br>
&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in if p1 then a else b<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in f 5 (Just 6)<br>
<br>So, I&#39;d say the results were intriguing but not terribly satisfying. My guess is many common uses would work out, but there would be hard-to-explain corner cases where the typechecker would need guidance or a desired level of polymorphism couldn&#39;t be achieved.
<br>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>&nbsp;- Ravi<br></div></div>