2016-10-24 20 views
5

Mã sau được biên dịch không thành công, nhưng nó được chuyển nếu tôi xóa chú thích specialized theo phương pháp dot.Đây có phải là lỗi chuyên ngành của scala không?

Scala đang Á hậu phiên bản 2.12.0-RC2 - Copyright 2002-2016, LAMP/EPFL và Lightbend, Inc.

abstract class Op[@specialized Left, @specialized Right] { 
    @specialized 
    type Result 

    def r: Numeric[Result] 
    def times(left: Left, right: Right): Result 
} 


object Op { 

    implicit object IntDoubleOp extends Op[Int, Double] { 
    type Result = Double 
    val r = implicitly[Numeric[Double]] 
    def times(left: Int, right: Double): Double = left * right 
    } 
} 


object calc { 

    def dot[@specialized Left, @specialized Right](xs: Array[Left], ys: Array[Right]) 
      (implicit op: Op[Left, Right]): op.Result = { 
    var total = op.r.zero 
    var index = xs.length 
    while(index > 0) { 
     index -= 1 
     total = op.r.plus(total, op.times(xs(index), ys(index))) 
    } 
    total 
    } 
} 

test.scala:31: error: type mismatch; 
found : op.Result 
required: op.Result 
    total 
    ^
one error found 

Dưới đây là một cố gắng không có may mắn:

//cat Ops.scala 
import scala.{ specialized => sp } 

trait OpsResult { 
    type N 
} 

trait SymOps extends OpsResult { 
    @sp override type N 
    def zero: N 
    def plus(left: N, right: N): N 
} 

trait AsyOps[@sp L, @sp R] extends OpsResult { 
    @sp override type N 
    def times(left: L, right: R): N 
} 

trait MixOps[@sp L, @sp R] extends AsyOps[L, R] with SymOps 

object MixOps { 
    trait DoubleOps extends SymOps { 
    override type N = Double 
    def zero: Double = 0.0 
    override def plus(left: Double, right: Double): Double = left + right 
    } 
    trait IntDoubleOps extends AsyOps[Int, Double] { 
    override type N = Double 
    override def times(left: Int, right: Double): Double = left * right 
    } 

    implicit object MixIntDouble extends IntDoubleOps with DoubleOps 
} 

object Test { 
    def dot[@sp L, @sp R](xs: Array[L], ys: Array[R]) 
     (implicit op: MixOps[L, R]): op.N = { 
    op.zero 
    } 
} 

$ scalac Ops.scala 
Ops.scala:36: error: type mismatch; 
found : op.N 
required: op.N 
    op.zero 
    ^
one error found 

Trả lời

5

Đây là một lỗi (cũng tái tạo trên 2.11.x). Tôi đã liên lạc với những người ở LightBend, và điều này chắc chắn là một điều kỳ quặc với việc tạo mã cho các kiểu chuyên biệt và phụ thuộc vào đường dẫn. Tôi đã thu hẹp nó xuống đến một sinh sản slim:

trait M[@specialized T] { 
    type Res 
    def res: Res 
} 

object Test { 
    def m[@specialized T](op: M[T]): op.Res = op.res 
} 

Các biểu tượng cho op sẽ không được đồng bộ và sẽ không biên dịch như bạn thấy trong mã của bạn. @AdriaanMoors has opened a bug liên quan đến vấn đề này.

Adriaan cũng đã chỉ cho tôi this blog post bởi Aleksandar Prokopec chỉ ra một số điểm ẩn trong việc tạo mã @specilization.

Các vấn đề liên quan