如何专门处理Scala中的类型投影?

如何专门处理Scala中的类型投影?,scala,types,Scala,Types,问题陈述 考虑一个类型T,它包含一个抽象类型成员a: trait T { type A } 我想创建一个类,它采用T0,我看不出它是如何工作的。专门化是在编译类时完成的,当时,A是未知的。这是编译器的限制;通常不能专门化类型参数的元素。然而,就我的目的而言,提议的技巧已经足够好了: trait Types { type A type B } trait GenOps[@specialized A, @specialized B] { ... } trait Ops[T &l

问题陈述

考虑一个类型
T
,它包含一个抽象类型成员
a

trait T {
  type A
}

我想创建一个类,它采用
T0,我看不出它是如何工作的。专门化是在编译类时完成的,当时,
A
是未知的。

这是编译器的限制;通常不能专门化类型参数的元素。然而,就我的目的而言,提议的技巧已经足够好了:

trait Types {
  type A
  type B
}

trait GenOps[@specialized A, @specialized B] {
  ...
}

trait Ops[T <: Types] extends GenOps[T#A, T#B]
特征类型{
A型
B型
}
性状基因组[@specialized A,@specialized B]{
...
}

trait Ops[T我的想法是,我希望在一个实现
类Bar extensed Foo[S]
中使用专门的方法,其中
S我更新了这个问题,以便更明确地说明装箱是如何出现的,以及如何通过专门化删除装箱。
trait SpecializedFoo[@specialized A0, T0 <: T] {
  def foo(a: A0, f: A0 => A0) = f(a)
}
class Foo2[T0 <: T] extends SpecializedFoo[T0#A, T0]
trait ExplicitT extends T {
  type A = Double
}

object Test {
  def test1 = (new Foo[ExplicitT]).foo(1.0, _ + 1.0)
  def test2 = (new Foo2[ExplicitT]).foo(1.0, _ + 1.0)
}
public double test1();
  Code:
   Stack=4, Locals=1, Args_size=1
   0:   new #16; //class Foo
   3:   dup
   4:   invokespecial   #18; //Method Foo."<init>":()V
   7:   dconst_1
   8:   invokestatic    #24; //Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double;
   11:  new #26; //class Test$$anonfun$test1$1
   14:  dup
   15:  invokespecial   #27; //Method Test$$anonfun$test1$1."<init>":()V
   18:  invokevirtual   #31; //Method Foo.foo:(Ljava/lang/Object;Lscala/Function1;)Ljava/lang/Object;
   21:  invokestatic    #35; //Method scala/runtime/BoxesRunTime.unboxToDouble:(Ljava/lang/Object;)D
   24:  dreturn
  LineNumberTable: 
   line 13: 0


public double test2();
  Code:
   Stack=5, Locals=1, Args_size=1
   0:   new #38; //class Foo2
   3:   dup
   4:   invokespecial   #39; //Method Foo2."<init>":()V
   7:   dconst_1
   8:   new #41; //class Test$$anonfun$test2$1
   11:  dup
   12:  invokespecial   #42; //Method Test$$anonfun$test2$1."<init>":()V
   15:  invokeinterface #48,  4; //InterfaceMethod SpecializedFoo.foo$mcD$sp:(DLscala/Function1;)D
   20:  dreturn
  LineNumberTable: 
   line 14: 0
trait T {
  type A
  def x: A
  def f: A => Double
}

class Foo[T0 <: T] {
  def foo(t: T0) = t.f(t.x)
}
trait Types {
  type A
  type B
}

trait GenOps[@specialized A, @specialized B] {
  ...
}

trait Ops[T <: Types] extends GenOps[T#A, T#B]