Last active
August 29, 2015 14:13
-
-
Save tixxit/2bba6c7d27a3eed0f779 to your computer and use it in GitHub Desktop.
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
object MiniboxingReflection { | |
... | |
def mbCast[A]: MbCast[A, _] | |
} | |
sealed trait MbCast[A, @mb B] { | |
def from(a: A): B | |
def to(b: B): A | |
def fromTC[F[_]](fa: F[A]): F[B] | |
def toTC[F[_]](fb: F[B]): F[A] | |
} | |
class IntMbCast[T] extends MbCast[T, Int] | |
class LongMbCast[T] extends MbCast[T, Long] | |
class FloatMbCast[T] extends MbCast[T, Float] | |
class DoubleMbCast[T] extends MbCast[T, Double] | |
... |
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
sealed trait Point2[@mb A] { | |
def x: A | |
def y: A | |
... | |
} | |
case class IntPoint2(x: Int, y: Int) extends Point2[Int] | |
case class DoublePoint2(x: Double, y: Double) extends Point2[Double] | |
case class GenPoint2[A](x: A, y: A) extends Point2[A] | |
object Point2 { | |
def apply[@mb A](x: A, y: A): Point2[A] = MiniboxingReflection.mbCast[A] match { | |
case (cast: IntMbCast) => cast.toTC(IntPoint2(cast.from(x), cast.from(y))) | |
case (cast: DoubleMbCast) => cast.toTC(DoublePoint2(cast.from(x), cast.from(y))) | |
case _ => GenPoint2(x, y) | |
} | |
} | |
In general, I'd be afraid to have the higher-order convertors:
def fromTC[F[_]](fa: F[A]): F[B]
def toTC[F[_]](fb: F[B]): F[A]
Since they only scale to one type parameter, not more :(
@VladUreche yeah, the casts are what I would've done otherwise, and aren't too bad (which is why I love what you have already). I fear the 2nd example would require some allocations and I was mostly hoping to get rid of the casts without any extra allocations (just *Point2
)! But just being able to pattern match on the specialized type without a ClassTag
solves this problem, so I'm happy anyway :)
The more I think about it, the more I'm happy with just reifiedType[A]
. Being able to pattern match on the type solves all my problems.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@tixxit, with the proposed reflection, you would have to do:
I would argue the last
.asInstanceOf[Point2[A]]
is not that ugly. The really ugly part is casting the components. So what if theSimpleType
s would have aConvertType
counterpart:That could be implemented in a pretty simple way, with a separate extractor. WDYT about this?