-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Closed
Description
Consider the following:
import scala.reflect.Selectable.reflectiveSelectable
type Mappable[F[_], A] = {
def map[B](f: A => B): F[B]
}
def doMap[F[x] <: Mappable[F, x], A, B](fa: F[A], f: A => B): F[B] =
fa.map(f)The existence of a contract-abiding map method seems to be guaranteed at compile-time.
@Adam-Vandervorst is working on a macroloop project which uses macros to vastly improve the performance of certain collections operations, and such restrictions allow for an easy way to verify that a generated for-comprehension would be valid:
type ForComp[F[_], A] = {
def map[B](f: A => B): F[B]
def flatMap[B](f: A => F[B]): F[B]
def withFilter(f: A => Boolean): F[A]
}
def example[F[x] <: ForComp[F, x], A, B, C](fa: F[A], f: A => F[B], g: B => Boolean, h: B => C): F[C] =
for {
a <- fa
b <- f(a) if g(b)
} yield h(b)Note that determining whether a subtyping is valid doesn't require reflection:
> scala
Welcome to Scala 3.1.3 (17.0.3, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> summon[String <:< { def length(): Int }]
val res0: String =:= String = generalized constraintSo my thoughts are that, once we've determined that the subtyping is valid, we should know that the reflective call is valid, right?
Adam-Vandervorst
Metadata
Metadata
Assignees
Labels
No labels