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