2015-08-18 11 views
6

Według Scala Language Specification,Dlaczego typy złożone o różnej kolejności składników są równoważne w Scali?

dwóch rodzajów związków są równoważne, gdy sekwencje są równoważne ich składnik parami i występują w takiej kolejności, a ich udoskonalenia są równoważne. Dwa udoskonalenia są równoważne, jeśli wiążą te same nazwy, a modyfikatory, typy i ograniczenia każdej deklarowanej jednostki są równoważne w obu udoskonaleniach.

Biorąc jednak pod uwagę

trait A { val a: Int } 
trait B { val b: String } 

Dostaję

scala> implicitly[A with B =:= B with A] 
res0: =:=[A with B,B with A] = <function1> 

to są one uważane za równoważne, chociaż kolejność elementów jest inny. Czemu?

+0

Czy jesteś pewien, że to ta sama koncepcja? Skala skalowania dla '=: =' nie zawiera wzmianki o "równoważności", a sekcja o specyfikacji języka dotycząca równoważności typów nie wymienia '=: =', więc wydaje mi się, że są to po prostu różne rzeczy. –

+0

@ChrisMartin "Instancja" A =: = B "świadczy o tym, że typy" A "i" B "są równe." - Zakładam, że "równy" i "równoważny" oznaczają to samo, czy ja tu się mylę? – exlevan

+1

Ponadto, dla mnie, gdy "równorzędne" i "równe" nie są takie same, to drugie jest bardziej rygorystyczne niż poprzednie (A i B są równoważne, co oznacza, że ​​można je wymieniać, ale niekoniecznie są tym samym podmiotem) . Jednak tutaj jest odwrotnie, co wydaje się być sprzeczne z intuicją. Rzeczywiście skaladoc dla 'Predef. =: =' Mówi "Występowanie A =: = B świadczy o tym, że typy A i B są ** równe **" podczas gdy scala spec (cytowane powyżej) definiuje ** równoważność typu ** (o czym świadczy "Type # =: ="). Ale równoważność ('Type # =: =') jest tutaj bardziej rygorystyczna niż równość 'Predef. =: ='. To dziwne. –

Odpowiedz

3

Myślę, że dowody z =:= tylko potwierdzają, że każda z nich jest górną granicą drugiej.

trait A; trait B 

import scala.reflect.runtime.{universe => ru} 

val ab = ru.typeOf[A with B] 
val ba = ru.typeOf[B with A] 
ab =:= ba // false! 
ab <:< ba // true! 
ba <:< ab // true! 

Domniemana od Szablony można uzyskać w zasadzie jeśli LUB (X, Y) X == == Y, bo wówczas niejawna rozdzielczości znajdzie =:=.tpEquals z wywnioskować górnej granicy.

To jest najprawdopodobniej to, czego chcesz, ponieważ oznacza to, że możesz traktować jeden typ jako drugi, i to działa, ponieważ członkowie A with B są równi członkom B with A, nawet jeśli linearyzacja cechy w implementacjach jest różna .

Powiązane problemy