-
Notifications
You must be signed in to change notification settings - Fork 533
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
Lazy can't see through public -> private type aliases #942
Comments
Having poked this a bit more, I wonder if it's some weird interaction between Replacing type ValidatedChainString[A] = cats.data.Validated[Chain[String], A]
{
implicit def mkTypeClassLazy[F[_]](implicit F: Lazy[cats.Functor[F]]): TC[F] = ???
implicitly[TC[ValidatedChainString]]
}
EDIT: the required implicits are re-declared on the |
You could try this patch: #797 |
No joy, unfortunately: I applied this patch on top of 2.3.3 and it still doesn't work. Taking a quick look at the patch, it seems that this is specific to shapeless' |
Yes, but they are related (it's a similar encoding). So I hoped that the fix to dealias less would help in this case as well. But no luck... |
Okay I'm building a test case and I've found something interesting: it seems to be caused by the specific way in which the packages are laid out in cats. A minimal reproduction of this layout is as follows: trait TC[F[_]]
object a {
// 1. the Impl class is package-private here
private[a] object FooImpl {
// Zero-overhead newtype
private[a] type Base
private[a] trait Tag extends Any
type Type[+A] <: Base with Tag
implicit def mkTC: TC[Foo] = new TC[Foo] {}
}
// 2. we then re-export the "nice" type alias
type Foo[+A] = FooImpl.Type[A]
}
// This works
implicitly[TC[a.Foo]]
// This doesn't
implicitly[Lazy[TC[a.Foo]]] The |
And having discovered that I've just managed to solve my (original) problem: simply explicitly re-importing the implicits I need allows {
implicit def mkTypeClassLazy[F[_]](implicit F: Lazy[cats.Functor[F]]): TC[F] = ???
implicitly[TC[ValidatedString]] // works
import cats.data.NonEmptyChain._
implicitly[TC[ValidatedNecString]] // now works again
} |
Thanks for the analysis ... very helpful. If you're building on 2.13, would you mind trying to replace |
Compiling with scala 2.13.1, a by-name implicit works as expected. Assuming the definition of def implicitByName[A[_]](implicit tc: => TC[A]) = println { tc }
def implicitByLazy[A[_]](implicit tc: Lazy[TC[A]]) = println { tc }
// This works as expected
implicitByName[a.Foo]
// This doesn't work without explicit re-import
import a.Foo._
implicitByLazy[a.Foo] |
Ok I think that's another instance of scala/bug#6794 - the implicit is accessible when inferred by the compiler but not when written down by the user (and having a macro generate it is morally equivalent to it being written down by the user). So I don't think anything could be done in shapeless to fix it. |
It's possible that a bit less dealiasing in the I think it's a mistake to rely on constructions which depend on aliases having different properties from their alisees (IOW, I think this is a problem with the newtype implementation) ... we should have referential transparency at the type level as well as the term level. I'll leave this open for a bit, but I'm inclined to close it. |
Thanks all for your input on this. Agreed, it seems like it's not something shapeless can reasonably fix, so I'm happy for you to close. The workaround (for now at least) is to explicitly re-import the necessary implicits. It also seems like there are other issues cats with newtypes, so I will comment there and link back to this issue. |
Java: OpenJDK 1.8.0_202
Scala: 2.12.4
shapeless: 2.3.3
Minimal reproduction: I believe all four cases shown below should compile, but only the first three do. The fourth fails because
Lazy
seems to lose the detailed knowledge ofNonEmptyChain[String]
(but works in the simple case where the first type parameter case is justString
).I've had a look through related tickets but I don't think this is covered elsewhere.
The text was updated successfully, but these errors were encountered: