以下元组:
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
}
由于
答案 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 HList
或Records
并实施Polymorphic function value或类似的东西。