Created
February 26, 2015 00:52
-
-
Save retronym/0cdb61fd74839c6fba93 to your computer and use it in GitHub Desktop.
Inference limitation, distilled from https://groups.google.com/d/msg/scala-user/WFkqE1KpnGA/TC9tvLvXNcQJ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait Test { | |
type Mapped[F[_]] | |
type sx[T] = T => String | |
trait fx[X] { | |
type λ[T] = T => X | |
} | |
def summon[F[_]]: Mapped[F] | |
// okay. Inference can unify the higher kinded type variable ?F with sx | |
summon : Mapped[sx] | |
// fails | |
summon : Mapped[fx[String]#λ] | |
// Why? | |
// | |
// `Mapped[fx[String]#λ]` is typechecked to `Test.this.Mapped[[T]T => String]` | |
// | |
// This happens in `typedSelect` -> `checkAccessible`, in which this computation occurs | |
// | |
// ------------------------------------------------------------------------------------ | |
// scala> type Mapped[F[_]] | |
// type sx[T] = T => String | |
// defined type alias Mapped | |
// defined type alias sx | |
// | |
// scala> trait fx[X] { | |
// | type λ[T] = T => X | |
// | } | |
// defined trait fx | |
// | |
// scala> :power | |
// ** Power User mode enabled - BEEP WHIR GYVE ** | |
// ** :phase has been set to 'typer'. ** | |
// ** scala.tools.nsc._ has been imported ** | |
// ** global._, definitions._ also imported ** | |
// ** Try :help, :vals, power.<tab> ** | |
// | |
// scala> val pre = typeOf[fx[String]] | |
// pre: $r.intp.global.Type = fx[String] | |
// | |
// scala> val sym = pre.member(TypeName("λ").encodedName) | |
// sym: $r.intp.global.Symbol = type λ | |
// | |
// scala> pre memberType sym | |
// res0: $r.intp.global.Type = [T]T => String | |
// | |
// scala> res0.getClass | |
// res1: Class[_ <: $r.intp.global.Type] = class scala.reflect.internal.Types$PolyType | |
// | |
// scala> showRaw(res0) | |
// res2: String = PolyType(List(TypeName("T")), TypeRef(ThisType(scala), scala.Function1, List(TypeRef(NoPrefix, TypeName("T"), List()), TypeRef(ThisType(java.lang), java.lang.String, List())))) | |
// ------------------------------------------------------------------------------------ | |
// | |
// The compiler would need to infer `F= [T]T => String`, but it never infers a polytype | |
// as a type argument as we don't have higher order unification. (https://issues.scala-lang.org/browse/SI-2712) | |
// | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment