&gt; Ocaml community (where most people strongly rely on type inference<br>&gt; and do not put types very often)<br><br>Well it&#39;s the same for Haskell.<br><br>
&gt; foo :: bar -&gt; foobar -&gt; barfoo<br>
&gt; foo b = let <b>fooAux :: foobar -&gt; barfoo</b>  -- You can comment it out<br>
 &gt;            fooAux fb = if f b fb<br>
 &gt;                        then fooAux (g b fb)<br>
 &gt;                        else h b fb<br>
 &gt;        in fooAux<br><br>Yes, I also like to write it that way, except you can <b>remove </b>fooAux type signature, and let GHC type inferer do its job, like in OCaml.<br>Plus, &#39;foo&#39; signature is merely documentation for you in that case.<br>

<br>&gt; I always prefer to minimize the number of specialized functions, since<br>
&gt; I hate jumping from parts of code to other parts of code to understand<br>&gt; what a function really does.<br><br>Too bad, that&#39;s one of the assets of functional programming. The more splitted you design your functions, the easier it is to reuse and test them afterwards. A good practice in C-like languages also, IMHO.<br>

You can just write subsome right under legSome, it doesn&#39;t break legibility, and if you think it&#39;s best tell your module to export only legSome.<br><br><br>...Or, remove/comment the inner type signatures ;)<br><br>

<br><div class="gmail_quote">2012/1/4 AUGER Cédric <span dir="ltr">&lt;<a href="mailto:sedrikov@gmail.com">sedrikov@gmail.com</a>&gt;</span><br><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

Le Tue, 3 Jan 2012 20:46:15 +0100,<br>
Yves Parès &lt;<a href="mailto:limestrael@gmail.com">limestrael@gmail.com</a>&gt; a écrit :<br>
<div class="im"><br>
&gt; &gt; Actually, my question is why the different type can&#39;t be unified<br>
&gt; &gt; with the<br>
&gt; inferred type?<br>
&gt;<br>
&gt; Because without ScopedTypeVariable, both types got expanded to :<br>
&gt;<br>
</div>&gt; legSome :: *forall nt* t s. LegGram nt t s -&gt; nt -&gt; Either String<br>
&gt; ([t], s)<br>
&gt;<br>
&gt; subsome :: *forall nt* t s. [RRule nt t s] -&gt;  Either String ([t], s)<br>
&gt;<br>
&gt; So you see subsome declare new variables, which *do not *match the<br>
&gt; *rigid *ones declared by legSome signature, hence the incompatibility.<br>
&gt;<br>
<br>
How ugly! I thought that Haskell didn&#39;t allow to mask type variables.<br>
<br>
Does that mean that I can do:<br>
<br>
foo :: (a -&gt; a) -&gt; (b -&gt; b) -&gt; a -&gt; a<br>
foo bar dummy =<br>
  let strange :: a -&gt; a<br>
      strange = dummy<br>
  in<br>
  foo<br>
<br>
(ok, that&#39;s dead code, but how misleading it would be!)<br>
<br>
Is there some way to enforce a typing error here?<br>
(I am pretty sure there is some flag to have explicit &#39;forall&#39;s,<br>
but I am not sure that it forces you to use &#39;forall&#39; explicitely.)<br>
<br>
I come from Coq community (where forall must be explicit) and Ocaml<br>
community (where most people strongly rely on type inference and do not<br>
put types very often). I didn&#39;t try this example on Ocaml.<br>
<div class="im"><br>
&gt; As we said before, you have three ways to work it out:<br>
&gt; 1) Use scoped type variables with explicit forall nt on legSome and<br>
</div>&gt; *no forall *on subsome, so that nt in subsome matches nt declared in<br>
<div class="im">&gt; legSome. 2) Don&#39;t give a type signature for subsome and let GHC find<br>
&gt; out which is its correct type.<br>
&gt; 3) Extract subsome so that it becomes a top-level function with a<br>
&gt; polymorphic type (Recommended).<br>
<br>
</div>In fact I first wanted to write directly the method without using<br>
auxiliary functions (I changed my mind since, as I redisigned my code<br>
and it wasn&#39;t possible [or at least natural for me] to put the code<br>
directly inlined).<br>
<br>
In fact I often do nested functions when there are free variables in<br>
the function. I particulary hate to have code like that:<br>
<br>
foo :: bar -&gt; foobar -&gt; barfoo<br>
foo b fb = if f b fb<br>
           then foo b (g b fb)<br>
           else h b fb<br>
<br>
as b is in fact invariant in the calls of &#39;foo&#39;; so I always rewrite<br>
this as:<br>
<br>
foo :: bar -&gt; foobar -&gt; barfoo<br>
foo b = let fooAux :: foobar -&gt; barfoo<br>
            fooAux fb = if f b fb<br>
                        then fooAux (g b fb)<br>
                        else h b fb<br>
        in fooAux<br>
<br>
that is more verbose, but I well see what are the recursive parameters,<br>
and I have the (probably wrong) feeling that it is better since<br>
function calls have less arguments.<br>
<br>
Here subsome was depending on the free variable &quot;sg&quot;, so I had to<br>
generalize it to do so even if I won&#39;t have benefits in having the<br>
ability to use it elsewhere (as it was the only place I wanted to use<br>
it).<br>
<br>
I always prefer to minimize the number of specialized functions, since<br>
I hate jumping from parts of code to other parts of code to understand<br>
what a function really does.<br>
<div class="HOEnZb"><div class="h5"><br>
&gt;<br>
&gt;<br>
&gt; Now, concerning the error I asked you to deliberately provoke, that&#39;s<br>
&gt; the quickest way I found to know what is the output of the type<br>
&gt; inferer, and maybe the only simple one.<br>
&gt; So this error is:<br>
&gt; &gt; Couldn&#39;t match expected type `Int&#39;<br>
&gt; &gt;               with actual type `[([Symbols nt t], [s] -&gt; t0)]<br>
&gt; &gt;                                 -&gt; Either [Char] ([t], t0)&#39;<br>
&gt; &gt;   In the expression: subsome :: Int<br>
&gt; GHC tells you the type it infers for subsome: [([Symbols nt t], [s]<br>
&gt; -&gt; t0)] -&gt; Either [Char] ([t], t0)<br>
&gt; The nt you see is the one from legSome, those messages show scoped<br>
&gt; variables. (You&#39;d get something like &#39;nt1&#39; or &#39;nt0&#39; if it was another<br>
&gt; variable, meant to be instanciated to a different type).<br>
&gt; This accords with your previous error message, which happens to give<br>
&gt; you more details about where the rigid type variable nt comes from:<br>
&gt; &gt;      `nt&#39; is a rigid type variable bound by<br>
&gt; &gt;           the type signature for<br>
&gt; &gt;             legSome :: LegGram nt t s -&gt; nt -&gt; Either String ([t],<br>
&gt; &gt; s)<br>
&gt;<br>
&gt; HTH.<br>
&gt;<br>
&gt; 2012/1/3 Yucheng Zhang &lt;<a href="mailto:yczhang89@gmail.com">yczhang89@gmail.com</a>&gt;<br>
&gt;<br>
&gt; &gt; On Wed, Jan 4, 2012 at 2:48 AM, Bardur Arantsson<br>
&gt; &gt; &lt;<a href="mailto:spam@scientician.net">spam@scientician.net</a>&gt; wrote:<br>
&gt; &gt; &gt; &#39;subsome&#39; to a different type than the one you intended -- and<br>
&gt; &gt; &gt; indeed one which can&#39;t be unified with the inferred type. (Unless<br>
&gt; &gt; &gt; you use ScopedTypeVariables.)<br>
&gt; &gt;<br>
&gt; &gt; Thanks for the reply.<br>
&gt; &gt;<br>
&gt; &gt; Actually, my question is why the different type can&#39;t be unified<br>
&gt; &gt; with the inferred type? Could you point me some related resources?<br>
&gt; &gt;<br>
&gt; &gt; _______________________________________________<br>
&gt; &gt; Haskell-Cafe mailing list<br>
&gt; &gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt; &gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt; &gt;<br>
<br>
</div></div></blockquote></div><br>