泛型泛型参数与另一个简单泛型参数的专门化

时间:2012-11-22 10:55:27

标签: scala

我目前正在开发一个包含机器学习高斯过程的项目。考虑到book中的示例和解释,我正在尝试为受过训练的GP对象的各种参数创建一个通用函数 - 因此,以下声明是最常用的一个(简单) )培训功能。

def train[T, M <: MatrixInverter[T], S <: Kernel[T]](): GP_Spawn[T] = null

(我已经删除了参数列表和实现,就在你想知道的时候。) T描述了数字类型,例如它可能是DoubleIntMatrixInverter[T]是强制执行calculateInverse功能的特征。 Kernel[T]是内核函数的相应特征。 正如你们中的一些人可能已经知道的那样,当使用 Cholesky-Decomposition 作为矩阵变换器时,可以改变高斯过程中的训练(以某种方式简化) - 因此,我考虑专门提到的功能以上。由于@specialized标记的文档,它应该是这样的:

def train[T, @specialized(CholeskyDecomposition[T]) M <: MatrixInverter[T], S <: Kernel[T]](): GP_Spawn[T] 

很明显,所有参数都或多或少取决于T,因为它们需要使用依赖于的某些变量(类型TVector[T]Matrix[T])它。如果我尝试编译上面提到的代码,scala-compiler(2.9.2)会抱怨

  

错误:未找到:值CholeskyDecomposition

我不确定这意味着什么,因为导入import algorithms.{CholeskyDecomposition, MatrixInverter}是正确的。此外,我很想知道CholeskyDecomposition的导入被标记为未使用的导入语句CholeskyDecomposition有一个伴侣,其中包含一些与算法本身相关的常量,但我不认为这个方面是导致此错误的原因。

任何可能导致此错误的想法?而且,如何解决它没有削减通用方法?

修改

在阅读完答案后正在考虑对我的代码进行一些重新排序时,我最终在运行时使用了类型匹配的解决方案。

val testMat = new Matrix[T](3, 3)
val testInv = fac(testMat)    
testInv match {
    case chol : CholeskyDecomposition[T] => println("Found Cholesky!")
    case _ => println("Found something different.")
}

它现在有效:)感谢所有人!

3 个答案:

答案 0 :(得分:5)

你只能使用基本类型专门化一个通用参数:IntDouble等。所以你可以专注T而不是Foo[T],即使{{1}是一个原始的。

答案 1 :(得分:3)

如果您有一个专门用于C类的课程T,那么

class D[@specialized T, C[T]](c: C[T]) { ... }

将使用T - C的专门版本。

无论如何,这就是你所需要的。对象的专业化是没有意义的;通用代码同样适用,因为无论如何非原始代码都是一个对象。

答案 2 :(得分:1)

根据API,它说:

Type T can be specialized on a subset of the primitive types by
specifying a list of primitive types to specialize at:

所以它基本上只适用于原始类型。