我有以下代码:
trait TypeLike
trait ArgLike
trait Predicate{
def name:String
}
case class Arg(name:String)
case class Predicate1[I1<:Arg,O<:TypeLike](name:String, arg1:I1, output:O, func: I1=> O) extends Predicate
case class Predicate2[I1<:Arg,I2<:Arg,O<:TypeLike](name:String, arg1:I1,arg2:I2, output:O, func: (I1,I2)=> O)
extends Predicate
如何在谓词特征中添加&#34; func&#34; 。我不知道如何用可变数量的输入来定义抽象函数。
答案 0 :(得分:1)
不幸的是,您必须使用HLists。以下是Shapeless HLists的示例:
import shapeless._
trait Predicate[Args <: HList, O <: TypeLike] {
implicit val lubWitness: LUBConstraint[Args, Arg]
def name: String
def func: Args => O
}
case class Predicate1[I1 <: Arg, O <: TypeLike](
name: String,
arg1: I1,
output: O,
func: I1 :: HNil => O
) extends Predicate[I1 :: HNil, O] {
implicit val lubWitness = implicitly[LUBConstraint[I1 :: HNil, Arg]]
}
case class Predicate2[I1 <: Arg, I2 <: Arg, O <: TypeLike](
name: String,
arg1: I1,
arg2: I2,
output: O,
func: I1 :: I2 :: HNil => O
) extends Predicate[I1 :: I2 :: HNil, O] {
implicit val lubWitness = implicitly[LUBConstraint[I1 :: I2 :: HNil, Arg]]
}
// Example instantiation
val p1 = Predicate1("Example", Arg("test"), new TypeLike {},
(args: Arg :: HNil) => { println(args(0)); ??? })
<强>解释强>
那么这里发生了什么? HList基本上是立体声的元组。让我们来看看我们的例子:
trait Predicate[Args <: HList, O <: TypeLike] {
Args <: HList
表示Args
是一个类型列表。 O <: TypeLike
是带有绑定的普通类型参数。
implicit val lubWitness: LUBConstraint[Args, Arg]
这说明我们需要证明HList Args
中的每个类型都是Arg
的子类型(我假设这是一个要求。
def func: Args => O
采用&#34;形状&#34;的HList的函数。 Args
并返回O
。 (如果您愿意,也可以将其写为方法。
case class Predicate1 /*snip*/ extends Preciate[I1 :: HNil, O]
Predicate1
是Predicate
,其参数列表包含一个I1
类型的元素。
implicit val lubWitness = implicitly[LUBConstraint[I1 :: HNil, Arg]]
检索并定义I1
是Arg
的子类型的见证(由于Predicate1
声明中的类型绑定,情况就属于这种情况。
答案 1 :(得分:-2)
作为类型参数的元组可以模拟类似于您的问题的东西。这种方法有两个局限。你应该在func调用上使用额外的parens,而元组对22项计数有限制。
trait TypeLike
trait ArgLike
trait Predicate[X, O] {
def name:String
def func(f: X): O
}
case class Arg(name:String)
case class Predicate1[I1<:Arg,O<:TypeLike, X <: Tuple1[I1]](name:String, arg1:I1, output:O) extends Predicate[X, O] {
override def func(f: X): O = ???
}
case class Predicate2[I1<:Arg,I2<:Arg,O<:TypeLike, X <: Tuple2[I1, I2]](name:String, arg1:I1,arg2:I2, output:O)
extends Predicate[X, O] {
override def func(f: X): O = ???
}