如何将(不同的)泛型传递给varags?

时间:2016-11-04 17:52:23

标签: scala

我有一个容器类

object OptimisationVariable {

  implicit class OptimisationVariableSeq[B](seq: Seq[OptimisationVariable[B]]) {
    def extract[A: ClassTag](variable: (OptimisationVariable[B] => A)): DenseVector[A] =
      DenseVector(seq.map(variable).toArray)
  }

}

final case class OptimisationVariable[B: ClassTag](startposition: B,       
                                                   startlearningrate: Double)

我想传递给我的算法:

class MyAlgorithm(optimisationVariable: OptimisationVariable*)

但是我得到了OptimisationVariable采用类型参数的错误。那讲得通。但是我希望传递能够传递不同种类的参数。由于optimisationVariable将成为Seq,我不确定我应该怎么做。 B将是IntDouble。 E.g。

new MyAlgorithm(OptimisationVariable(1, 2.0), OptimisationVariable(3.0, 4.0))

稍后我想决定该怎么做,具体取决于它是Int还是Double

2 个答案:

答案 0 :(得分:1)

如果您不打算限制B,使用存在类型就可以了:

final case class OptimisationVariable[B: ClassTag](
    startposition: B,
    startlearningrate: Double
)
case class MyAlgorithm(optimisationVariable: OptimisationVariable[_]*)
// and then
MyAlgorithm(OptimisationVariable(1, 1.0), OptimisationVariable(2, 1.1))

如果你打算将它们限制在某个上限,可以输入一些类型,你仍然很好。

如果您受到启发,尝试无形,如上面的评论所示,这是一本很好的入门书(不要担心!它简短而实用):shapeless-guide

答案 1 :(得分:0)

我简化了你的例子,据我所知,基本上你想要这个:

case class Ov[A](start: A, degree: Double)
case class MyAlg[L <: HList : *->*[Ov]#λ](ov: L)

MyAlg(Ov(1, 2):: Ov("Hello", 2) :: HNil) //compiles
MyAlg(1 :: HNil)     // won't compile

现在您可以传递任意数量的OptimizedVariables,保持其类型。 然后,如果你需要在它上面进行映射,你只需为你要使用的类型定义多态函数(来自无形)。

实际上,如果它们只是IntDouble,则可以

case class Ov1(start: Int \/ Double, degree: Double) // \/ from scalaZ
case class MyAlg1(ov: List[Ov1])

甚至使用无形(|v|)而不是\/

的联合类型