将Scala对象强制转换为泛型类型?

将Scala对象强制转换为泛型类型?,scala,generics,scalatest,Scala,Generics,Scalatest,首先,一些背景: 我目前正在为某一类问题编写一个通用的求解器,特别是Scala中的结构化SVM求解器。为了使用它,用户必须实现一个接口 考虑界面的简化版本: trait HelperFunctions[X, Y] { def func1(x: X, y: Y): Y def func2(y1: Y, y2: Y): Int } 以及一个简单的实现: object ImplFunctions extends HelperFunctions[Vector[Double], Doub

首先,一些背景:

我目前正在为某一类问题编写一个通用的求解器,特别是Scala中的结构化SVM求解器。为了使用它,用户必须实现一个接口

考虑界面的简化版本:

trait HelperFunctions[X, Y] {
    def func1(x: X, y: Y): Y
    def func2(y1: Y, y2: Y): Int
}
以及一个简单的实现:

object ImplFunctions extends HelperFunctions[Vector[Double], Double] {
    def func1(x: Vector[Double], y: Double): Double  = { ... }
    def func2(y1: Double, y2: Double): Int = { .. }
}
注意,实现必须以对象的形式提供

现在,问题是: 我需要编写一个诊断套件,帮助用户验证其功能的健全性。例如,健全性测试将涉及类似于func1的内容。。所有x和y都为正。为此,我使用ScalaTest编写了BDD风格的单元测试

请注意,诊断套件应该是通用的,以处理扩展HelperFunction[X,Y]的任何对象。 我计划如何进行这项工作的一个高层次的描述:首先提供为通用X和Y设计的所有健全性测试。然后,用户只需使用impl函数替换,比如说A???,并运行套件

但是,事实证明,我并没有找到一种优雅的方法来将impleFunctions视为通用的helperFunction[X,Y]。以下是我到目前为止所尝试过的:

import org.scalatest._

class ApplicationDiag extends FlatSpec {

  // Option 1:
  // Cast the ImplFunctions into a generic type
  // ERROR: type mismatch; found : ImplFunctions.type, required : HelperFunctions[X, Y]
  val helpers: HelperFunctions[X, Y] = ImplFunctions
  // OR
  def helpers[X, Y](): HelperFunctions[X, Y] = ImplFunctions


  // Option 2: User fills up the right side, no type specified for the value
  // WORKS. But, cannot explicitly state types
  val helpers = ImplFunctions

  "func1" should "be positive" in {
    // ... the check as described previously
   }

}
由于协方差的性质,我认为应该可以将一个类型的实例强制转换为它的超类型。但是,这似乎更难,因为这涉及到泛型。 有没有干净的方法可以做到这一点

注: 1.我完全接受诊断套件的替代设计。
2.真实世界的界面:以及一个真实世界的应用程序:

我不确定你是如何编写你的泛型测试的,但是也许你应该考虑使用.< /p> 我将使用稍微简单一点的界面来演示这个想法,但它应该很容易适用于您的问题。 例如,您有一个接口

trait Helpers[A] {
  def f(a: A): A
}
和一个实现

object IntImpl extends Helpers[Int] {
  def f(a: Int) = -a
}
不幸的是,Helpers[A]不需要对A进行任何约束。但您可能不想修改库

仍有可能为以下部分编写通用测试套件:

该套件可用于我们有数字类型类实现的每个A,例如Int

具体套件现在可以通过以下方式实例化:

new Diag(IntImpl)
或者如果测试框架需要一个类

class ImplDiag extends Diag(IntImpl)

这种方法的优点是它是完全类型安全的。您不必强制转换任何内容,Diag的签名清楚地指定了运行套件所需的内容。

如果您希望您的类型是co或contra variant,则应使用+X/-X语法将其声明为co或contra variant。你不需要投。
class ImplDiag extends Diag(IntImpl)