<div dir="auto">FYI, your Q2 (with no tyfam) is well-typed because of #15009</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, May 20, 2019, 11:01 Iavor Diatchki <<a href="mailto:iavor.diatchki@gmail.com">iavor.diatchki@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
thanks for the detailed response---I thought something like that might<br>
be happening, which is why I thought I'd better ask before reporting a<br>
bug.<br>
<br>
I wonder how we might make the error message a little more user<br>
friendly.   One idea would be to compute a couple of examples to show,<br>
after an ambiguity check fails.<br>
<br>
-Iavor<br>
<br>
On Sat, May 18, 2019 at 7:03 AM Ryan Scott <<a href="mailto:ryan.gl.scott@gmail.com" target="_blank" rel="noreferrer">ryan.gl.scott@gmail.com</a>> wrote:<br>
><br>
> Hi Iavor,<br>
><br>
> This is a feature in the sense that it is an expected outcome of the<br>
> OutsideIn(X) type inference algorithm (in particular, Section 5 of the<br>
> corresponding paper [1]). I'll try to explain the issue to the best of<br>
> my understanding.<br>
><br>
> The tricky thing about the Q3 data type:<br>
><br>
>     data Q3 = forall a. Q3 (forall b. (F b ~ Int) => T a b)<br>
><br>
> Is that there is a rank-n type with a /local/ equality constraint. In<br>
> order to ensure that the type of the Q3 data constructor is never<br>
> ambiguous, GHC tries to infer that Q3's type is always a subtype of<br>
> itself. As a part of this, GHC attempts to solve the following<br>
> implication constraint:<br>
><br>
>     forall a. forall b. (F b ~ Int) => (a ~ alpha)<br>
><br>
> Where `alpha` is a unification variable. GHC tries to find a unique,<br>
> most-general substitution that solves this constraint but ultimately<br>
> gives up and reports the "untouchable" error message you observed.<br>
><br>
> This is a bit strange, however. Upon first glance, this constraint<br>
> would appear to have a unique solution: namely, [alpha |-> a]. Why<br>
> doesn't GHC just use this? Ultimately, it's because OutsideIn(X) is<br>
> conservative: there may exist constraints that admit a unique solution<br>
> which it may fail to solve. This is explained in greater depth in<br>
> Section 5.2 of the paper, but the essence of this restriction is<br>
> because of the open-world assumption for type families. Namely, it's<br>
> possible that your Q3 data type might later be linked against code<br>
> which defines the following type family:<br>
><br>
>     type family G i a<br>
>     type instance G Int a = a<br>
><br>
> If that were the case, then the implication constraint above would no<br>
> longer have a unique solution, since there would exist another<br>
> substitution [alpha |-> G (F b) a] that is incomparable with [alpha<br>
> |-> a]. OutsideIn(X) was designed to only pick unique solutions that<br>
> remain unique solutions even if more axioms (i.e., type family<br>
> equations) are added, so for these reasons it fails to solve the<br>
> implication constraint above.<br>
><br>
> See also GHC issues #10651 [2], #14921 [3], and #15649 [4], which all<br>
> involve similar issues.<br>
><br>
> -----<br>
><br>
> I'm far from an expert on type inference, so I can't really offer a<br>
> better inference algorithm that would avoid this problem. The best you<br>
> can do, as far as I can tell, is to enable AllowAmbiguousTypes and<br>
> hope for the best. Even then, you'll still run into situations where<br>
> untouchability rears its ugly head, as in your `q3` definition. When<br>
> that happens, your only available option (again, as far as I can tell)<br>
> is to make use of TypeApplications. For example, the following /does/<br>
> typecheck:<br>
><br>
>     q3 :: Q3<br>
>     q3 = Q3 @Bool t<br>
><br>
> Hope that helps,<br>
><br>
> Ryan S.<br>
> -----<br>
> [1] <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/jfp-outsidein.pdf" rel="noreferrer noreferrer" target="_blank">https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/jfp-outsidein.pdf</a><br>
> [2] <a href="https://gitlab.haskell.org/ghc/ghc/issues/10651" rel="noreferrer noreferrer" target="_blank">https://gitlab.haskell.org/ghc/ghc/issues/10651</a><br>
> [3] <a href="https://gitlab.haskell.org/ghc/ghc/issues/14921" rel="noreferrer noreferrer" target="_blank">https://gitlab.haskell.org/ghc/ghc/issues/14921</a><br>
> [4] <a href="https://gitlab.haskell.org/ghc/ghc/issues/15649" rel="noreferrer noreferrer" target="_blank">https://gitlab.haskell.org/ghc/ghc/issues/15649</a><br>
> _______________________________________________<br>
> ghc-devs mailing list<br>
> <a href="mailto:ghc-devs@haskell.org" target="_blank" rel="noreferrer">ghc-devs@haskell.org</a><br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org" target="_blank" rel="noreferrer">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
</blockquote></div>