I'm working with a lot of code with type lambdas at the moment and noticed that IntelliJ is warning me that it's an "Advanced language feature: reflective call".
Sample code:
implicit def monoidApplicative[M](M: Monoid[M]) =
new Applicative[({ type f[x] = Const[M, x] })#f] {
def unit[A](a: => A): M = M.zero
override def apply[A,B](m1: M)(m2: M): M = M.op(m1, m2)
}
Note: I figure that this could be a bug the IntelliJ Scala plugin as it would make sense that type lambdas are resolved at compile time.
IDEA just gets confused because of the { } block. None of this code even exists at runtime.
Here is a small example. A generic identity method for types with one type argument:
def id[F[_], A](value: F[A]) = value
It is not possible to call this method with a type that takes two type arguments:
class Test[A, B]
id(new Test[Int, Int])
<console>:10: error: type mismatch;
found : Test[Int,Int]
required: F[A]
id(new Test[Int, Int])
But we can use a type lambda to define a function id2 that is implemented in terms of id:
def id2[F[_, _], A, B](value: F[A, B]) =
id[({ type f[x] = F[A, x] })#f, B](value)
id2(new Test[Int, Int])
res3: Test[Int,Int] = Test@1a53ac0c
Quite convoluted, but it works. Now let's look at the bytecode.
scala> :javap -c id2
...
public <F, A, B> F id2(F);
Code:
0: getstatic #19 // Field .MODULE$:L;
3: aload_1
4: invokevirtual #22 // Method .id:(Ljava/lang/Object;)Ljava/lang/Object;
7: areturn
...
As you can see, there is nothing left of all the type trickery. No reflection, nothing. Just java.lang.Object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With