lampepfl / dotty-feature-requests

Historical feature requests. Please create new feature requests at https://github.com/lampepfl/dotty/discussions/new?category=feature-requests
31 stars 2 forks source link

Language request: polymorphic (quantified) implicits #50

Open neko-kai opened 5 years ago

neko-kai commented 5 years ago

Polymorphic function values exist now, however currently they can't be discovered from existing polymorphic implicits:

trait MyMonad[F[_]] {
  def pure[A](a: A): F[A]
  def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
}

object MyMonad {
  type EitherMonad[E] = MyMonad[[A] =>> Either[E, A]]

  implicit def myMonadForEither[E]: EitherMonad[E] = new EitherMonad[E] {
    def pure[A](a: A) = Right(a)
    def flatMap[A, B](fa: Either[E, A])(f: A => Either[E, B]) = fa.flatMap(f)
  }
}
implicitly[[E] => () => EitherMonad[E]] // no implicit argument found

Specific kinds of polymorphic instances can be auto-lifted on library level, which is what we use in Scala 2:

private[MyMonad] type X
implicit def makePolymorphic[C[_[_]], F[_, _]](implicit c: C[[A] =>> F[X, A]]): [E] => () => C[[A] =>> F[E, A]] = {
  ([E] => () => c.asInstanceOf)
}
implicitly[[E] => () => EitherMonad[E]] // Found!

However, direct language support is highly desired!

Motivation for it is the same as for an existing haskell feature, quantified constraints.

LPTK commented 5 years ago

Perhaps worth noting: there is relevant previous work on polymorphic implicits; see COCHIS: Stable and Coherent Implicits.

Queries can be polymorphic too. For instance, the following example extracts the polymorphic implicit with a polymorphic query. implicit (Λα.(λ?α.(?α, ?α))) in ?(∀β.β ⇒ (β×β)))