Skip to content
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

Existential higher kinded type does not work #9445

Closed
scabug opened this issue Aug 24, 2015 · 7 comments · Fixed by scala/scala#6123
Closed

Existential higher kinded type does not work #9445

scabug opened this issue Aug 24, 2015 · 7 comments · Fixed by scala/scala#6123

Comments

@scabug
Copy link

scabug commented Aug 24, 2015

Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :paste
// Entering paste mode (ctrl-D to finish)

trait H[F[_, _]]
trait T[A, B]
val h:H[T] = null
val e:H[F] forSome { type F[A, B] } = h


// Exiting paste mode, now interpreting.

<console>:13: error: type mismatch;
 found   : H[T]
 required: H[_[A, B] <: Any]
Note: T <: Any, but trait H is invariant in type F.
You may wish to define F as +F instead. (SLS 4.5)
       val e:H[F] forSome { type F[A, B] } = h
                                             ^
@scabug
Copy link
Author

scabug commented Aug 24, 2015

Imported From: https://issues.scala-lang.org/browse/SI-9445?orig=1
Reporter: @Atry
See #9008

@scabug
Copy link
Author

scabug commented Aug 24, 2015

@Atry said:
Is it a regression to #9008 ?

@joroKr21
Copy link
Member

I don't think it's a regression of #9008

This issue is causing problems with implicit resolution for HKTs:

trait Functor[F[_]]
implicit val optFunctor: Functor[Option] = ???
implicit def genFunctor[F[_]]: Functor[F] = ???
implicitly[Functor[Option]] // ambiguous

Somehow the bounds of existential HKTs seem wrong to me:

  val universe = scala.reflect.runtime.universe.asInstanceOf[JavaUniverse]
  import universe._
  def bounds(sym: Symbol) = (sym.info.bounds.lo, sym.info.bounds.hi)
  trait T { type F[_] }
  println(bounds(symbolOf[F[Int] forSome { type F[_] }])) // ([_]Any,[_]Any)
  println(bounds(symbolOf[T#F[Int]])) // ([_]Nothing,[_]Any)
  println(bounds(symbolOf[A forSome { type A }])) // (Nothing,Any)

Setting the lower bound explicitly doesn't help:

println(bounds(symbolOf[F[Int] forSome { type F[_] >: Nothing }])) // ([_]Any,[_]Any)

Where are those created?

@joroKr21
Copy link
Member

The problem is here. The existentialBound for a HKT is a PolyType which gets thrown away here and replaced by hiBound(s).

@joroKr21
Copy link
Member

Fixing this reveals a deeper limitation though:

// This works:
scala> implicitly[H[T] <:< (H[F] forSome { type F[_, _] })]
res0: H[T] <:< H[_[_, _]] = <function1>

// But we can't create a value of that type:
scala> def hf: H[F] forSome { type F[_, _] } = ???
<console>:5: error: can't existentially abstract over parameterized type F
         lazy val $result = hf

@milessabin
Copy link

@joroKr21 I suspect that the restriction on existentially abstracting over parameterized types is obsolete ... my hunch is that it was introduced to mask some of the issues with higher kinded types that are touched on in this and related tickets.

I think that we should drop the restriction and fix the underlying issues that would reveal.

@joroKr21
Copy link
Member

Yes, that restriction manifested itself only in the REPL. It's not a problem in compiled code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants