Do Scala enter lambdas reflexive call cost?

I am working with a lot of code with type lambdas at the moment and noticed that IntelliJ warns me that it is an "Extended language function: reflexive call".

Code example:

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 believe this may be a bug of the IntelliJ Scala plugin, as it would be reasonable that the lambdas type is allowed at compile time.

+6
source share
1 answer

IDEA is simply confused because of the { } block. None of these codes even exist at runtime.

Here is a small example. General identification 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 the lambda type to define the id2 function, which 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 

Pretty confusing, but it works. Now 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, nothing remains of all the type tricks. No reflection, nothing. Just java.lang.Object .

+8
source

All Articles