Scala 以任意数量的参数作为参数的函数

Scala 以任意数量的参数作为参数的函数,scala,functional-programming,Scala,Functional Programming,我有一个方法eval,它获取函数和参数的列表,目前我正在为每个可能的函数编写案例。我怎样才能写得更通俗 implicit class Expression(p: Product) { def eval = p.productIterator.toList match { case (f: ((Any) => Any)) :: p1 :: Nil => f(p1) case (f: ((Any, Any) => Any)) :: p1 :: p2 :: Nil

我有一个方法eval,它获取函数和参数的列表,目前我正在为每个可能的函数编写案例。我怎样才能写得更通俗

implicit class Expression(p: Product) {
  def eval = p.productIterator.toList match {
    case (f: ((Any) => Any)) :: p1 :: Nil => f(p1)
    case (f: ((Any, Any) => Any)) :: p1 :: p2 :: Nil => f(p1, p2)
    case (f: ((Any, Any, Any) => Any)) :: p1 :: p2 :: p3 :: Nil => f(p1, p2, p3)
  }
}
def print = (x: Any) => println(">> " + x)
def add = (x: Any, y: Any) => x.asInstanceOf[Int] + y.asInstanceOf[Int]
(print, "test").eval
(add, 2, 3).eval

您可以使用shapeless编写类似的代码,它的好处是它是类型安全的,并且在编译时进行检查(与在
Expression.eval中使用
Any
相比)

如果case类遵循相同的格式(首先是函数,然后是该函数的正确参数),也可以将其用于case类:


您可以使用shapeless编写类似的代码,它的好处是它是类型安全的,并且在编译时进行检查(与在
Expression.eval中使用
Any
相比)

如果case类遵循相同的格式(首先是函数,然后是该函数的正确参数),也可以将其用于case类:


您可以使用shapeless编写类似的代码,它的好处是它是类型安全的,并且在编译时进行检查(与在
Expression.eval中使用
Any
相比)

如果case类遵循相同的格式(首先是函数,然后是该函数的正确参数),也可以将其用于case类:


您可以使用shapeless编写类似的代码,它的好处是它是类型安全的,并且在编译时进行检查(与在
Expression.eval中使用
Any
相比)

如果case类遵循相同的格式(首先是函数,然后是该函数的正确参数),也可以将其用于case类:


可能的复制可能的复制可能的复制你能告诉我一个方法来实现它而不变形和类型安全,我真的很好奇,有没有可能用更简单的方法来实现它?像这样的泛型编程,在没有形状和类型安全的情况下,在Scala中是不可能的,我真的很好奇,有没有可能用更简单的方法来实现它?像这样的泛型编程,在没有形状和类型安全的情况下,在Scala中是不可能的,我真的很好奇,有没有可能用更简单的方法来实现它?像这样的泛型编程,在没有形状和类型安全的情况下,在Scala中是不可能的,我真的很好奇,有没有可能用更简单的方法来实现呢?像这样的泛型编程,在函数算术和参数类型上进行抽象,在Scala中不可能没有形状。
import shapeless._
import ops.hlist._
import syntax.std.function._
import ops.function._

def eval[P <: Product, G <: HList, F, L <: HList, R](
  p: P
)(implicit 
  gen: Generic.Aux[P, G], 
  ihc: IsHCons.Aux[G, F, L], 
  ftp: FnToProduct.Aux[F, L => R]
) = { 
  val l = gen.to(p)
  val (func, args) = (l.head, l.tail)
  func.toProduct(args)
}
def add(a: Int, b: Int) = a + b
val stringLength: String => Int = _.length

eval((add _, 1, 2))             // Int = 3
eval((stringLength, "foobar"))  // Int = 6
eval((stringLength, 4))         // does not compile
case class Operation(f: (Int, Int) => Int, a: Int, b: Int)
eval(Operation(_ + _, 1, 2))    // Int = 3
eval(Operation(_ * _, 1, 2))    // Int = 2