Open
Description
Reproduction steps
Scala version: 2.13.11, 2.13.12
Works in: 3.3.1
type Id[A] = A
trait Extract[T, F[_]] {
def apply(json: AnyRef): F[T]
}
object Extract {
implicit val extractString: Extract[String, Id] =
(json: AnyRef) => "baz"
}
final class PartiallyAppliedExtract[T](val entity: Entity) extends AnyVal {
def apply[F[_]](key: String)(implicit extract: Extract[T, F]): F[T] =
extract(null)
}
trait Entity {
final def extract[T]: PartiallyAppliedExtract[T] =
new PartiallyAppliedExtract(this)
}
val e: Entity = new Entity {}
printf(e.extract[String]("foo"))
Problem
The type constructor used for the return type is inferred by the implicit chosen by the compiler, meaning we can use different effects based on the return type. When using the type Id[A] = A
type alias (to indicate that there is no effect), the compiler seems to "forget" the type constructor used, and cannot infer that Id[String]
is the same as String
.
In the example above, adding an implicit conversion Id[A] => A
allows the snippet above to compile, however with one warning: the implicit conversion is unused. But the fact that the code compiles with the implicit conversion in scope hints that the compiler in fact knows that the type constructor is Id[_]
, and uses the implicit conversion.