2016-05-10 12 views
6

Pracuję z dużą ilością kodu z typem lambdas w tej chwili i zauważyłem, że IntelliJ ostrzega mnie, że jest to "Zaawansowana funkcja językowa: połączenie refleksyjne".Czy koszt lambda typu Scala wywołania odblaskowego?

Przykładowy kod:

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) 
    } 

Uwaga: ja zorientować, że może to być błąd plugin IntelliJ Scala jak miałoby to sens, że lambdas typu są rozwiązywane w czasie kompilacji.

+2

Nie znam odpowiedzi na twoje pytanie, ale jeśli mówisz, że masz wiele lambdasów w swoim kodzie, polecam sprawdzenie https://github.com/non/kind-projector –

+0

Być może powinienem. Masz pomysł, czy wtyczka IJ's Scala ma na to wsparcie? –

+1

Sam tego nie wykorzystałem, ale zgodnie z tym: http://blog.jetbrains.com/scala/2015/07/31/inline-refactoring-for-type-aliases-and-kind-projector-support/ powinien być wspierany od dłuższego czasu. –

Odpowiedz

8

IDEA po prostu zostaje zdezorientowana z powodu bloku { }. Żaden z tych kodów nie istnieje nawet w środowisku wykonawczym.

Oto mały przykład. Ogólny sposób tożsamość dla typów z jednego typu argumentu:

def id[F[_], A](value: F[A]) = value 

Nie jest możliwe wywołanie tej metody z typem, który trwa dwa argumenty typu:

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]) 

Ale możemy użyć typu lambda zdefiniuj funkcję id2, która jest zaimplementowana pod kątem 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] = [email protected] 

Dość zawiłe, ale działa. Teraz spójrzmy na kod bajtowy.

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 

... 

Jak widać, nic nie zostało z tego rodzaju oszustwa. Bez refleksji, nic. Tylko java.lang.Object.