将元组传递给curry函数

时间:2016-03-29 12:32:13

标签: scala

以下元组:

val i = (1, 2, 3, 4, 5, 6)

需要作为参数传递给curried函数,如下所示:

f("param") (i)

定义curried函数时,定义接收元组的参数类型的正确方法是什么?

def f(s:String) (myTuple:???) = {
  val (a, b, c, d, e. f) = myTuple
  // more code
}

我想避免在定义参数类型时指定元组中每个元素的数量和类型。换句话说,我想避免这个:

def f(s:String) (myTuple:(Int, Int, Int, Int, Int, Int)) = {
  val (a, b, c, d, e. f) = myTuple
  // more code
}

由于

1 个答案:

答案 0 :(得分:4)

val i = (1, 2, 3, 4, 5, 6)

def f(s:String)(myTuple: (Int, Int, Int, Int, Int, Int)) = {
  val (a, b, c, d, e, f) = myTuple
}

f("param")(i)

Currying无论如何都不会改变你声明函数参数的方式:

val i = (1, 2, 3, 4, 5, 6)

def f(myTuple: (Int, Int, Int, Int, Int, Int)) = {
  val (a, b, c, d, e, f) = myTuple
}

f(i)

由于您有六个参数,我建议您使用案例类来记录其含义:

case class Params(p1: Int, p2: Int, someFancyName: Int, otherName: Int, p5: Int, p6: Int)

def f(myTuple: Params) = {
  val Params(a, b, c, d, e, f) = myTuple
}

val i = (1, 2, 3, 4, 5, 6)

f(Params.tupled(i))

从调用它的人那里可以更容易地理解你的函数参数,因为每个参数在案例类中都有一个名称

我看到你编辑了你的问题:如果你想避免指定元素的数量,你可以使用像磁铁模式的东西,并为每个元组实现磁铁,或者你可以使用宏。

如果您使用磁铁模式,您将必须实施许多不同的实施,具体取决于参数的数量和类型(您在实施中不是通用的,您必须知道如何处理你的论点)。这是元组最多三个项目的简短示例:

abstract class TupleMagnet[T](t: T) {
  def apply(): Unit
}

object TupleMagnet {
  implicit def tuple1Magnet[A](t: Tuple1[A]) = new TupleMagnet(t) {
    def apply() =  { println(t._1) }
  }
  implicit def tuple2Magnet[A, B](t: (A, B)) = new TupleMagnet(t) {
    def apply() = t match { case (a, b) =>  println(""+a + b) }

  }
  implicit def tuple3Magnet[A, B, C](t: (A, B, C)) = new TupleMagnet(t) {
    def apply() = t match { case (a, b, c) =>  println(""+a + b + c) }
  }
}


def f[T](magnet: TupleMagnet[T]) = magnet()

val i = (1, 2, 3)
f(i)

val j = (1, 2)
f(j)

参数数量/类型中通用的另一个选项可能是使用shapeless HListRecords并实施Polymorphic function value或类似的东西。