-
Notifications
You must be signed in to change notification settings - Fork 21
type aliases breaking implicit resolution #10582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I chatted with @fommil about this and it is with @milessabin is this surprising? I kind of expected it to be opaque to aliasing. Or maybe this has nothing to do with |
Could you try and put together a small self-contained reproduction? |
Now that I look at it more closely the problem is that the shapes are different. type F[A, B] = Validation[A, B]
type G[A, B] = Validation[NonEmptyList[A], B] Or, to simplify type F[A] = List[A]
type G[A] = List[Option[A]] The first has an implicit functor for instance, but the second doesn't. So I think this is expected behavior. |
Happy for me to close this? |
I don't believe this is "expected" behaviour. What would be the negative consequences of implicit resolution doing a final step where all types are dealiased? |
It's not clear when this will or won't resolve... e.g. this works
|
There are several issues related with aliases and implicit resolution/inference: #5070, #8740, #8709. This #8709 (comment) could point to something variance-related (at least in the scalaz case); NonEmptyList is invariant, Validation covariant. |
Thanks for pushing the branch with the reproduction. I believe this is an faithful minimization: abstract class C {
type V[A]
type N[A]
type VN[A] = V[N[A]]
type TC1[_[_]]
type TC2[_]
def infer[M[_], A](ma: M[A])(implicit M: TC1[M], A: TC2[A]) = ???
def ok1(vn: V[N[Int]])(implicit V: TC1[V], NInt: TC2[N[Int]]) = infer(vn)
def nok1(vn: VN[Int] )(implicit V: TC1[V], NInt: TC2[N[Int]]) = infer(vn)
def ok2(vn: VN[Int] )(implicit V: TC1[V], NInt: TC2[N[Int]]) = infer(vn : V[N[Int]])
} In The inferred type argument for The Scala typechecker doesn't support backtracking, so dealiasing (and base-typing) is only done to get to the first plausible unification. I suspect that backtracking would be computationally unfeasible, remembering that method type parameter inference also occurs for the candidate expressions to satisfy implicit arguments, and so on recursively. So even just a branching factor of 2 in the search can cause a blowup of 2^N in the implicit search time, where N is the depth of the implicit search tree. It would be interesting to think of ways to pose the problem of type parameter and implicit term inference in some sort of unified way that might lend itself to a computationally feasible search. But I don't see anything we can do in the meantime to make this work as you'd hope. |
Thanks for finding the core problem. How about workarounds where we could somehow indicate to the compiler that a certain implicit should be treated as having two names? |
In scala/scala#7662 @adriaanm mentions:
Does that change the feasibility of fixing this? In other words, should this be reopened as no longer "Won't Fix"? |
in scalaz (but also in cats)
note that the code is identical in both but the first code is using the type alias
ValidationNel[..., ...]
, and the second is using raw typeValidation[NonEmptyList[...], ...]
The text was updated successfully, but these errors were encountered: