在无限参数上应用函数

时间:2013-03-28 16:01:49

标签: scala functional-programming

我想编写一个可以使用此语法获取无限参数的函数

myfunc arg1 arg2 arg3 .... 我尝试了一些使用curring但没有任何帮助 我试图让它递归,但然后scala编译器说: “scala递归方法需要结果类型” 递归:

def func(x:Int) = {
  doSomething(x); myVal:Int=>func(myVal)
}

感谢帮助者

2 个答案:

答案 0 :(得分:6)

易:

scala> class FRP1 { def apply(args: Int*) = args.mkString("{", ", ", "}") }
defined class FRP1

scala> val frp11 = new FRP1
frp11: FRP1 = FRP1@147611bd

scala> frp11(1)
res0: String = {1}

scala> frp11(1, 2)
res1: String = {1, 2}

scala> frp11(1, 2, 3)
res2: String = {1, 2, 3}

答案 1 :(得分:6)

所以你寻找的函数接受某种类型的参数,并且必须返回一个函数,该函数接受相同类型的参数并返回一个带有相同类型参数的函数,依此类推,无穷无尽。

这里的问题是这个函数的类型是:

T[X] = X => T[X]

也就是说,它是一种递归的自引用类型。因为它是自引用的,所以我们必须将其命名为仅在其自身内重用它的目的(不幸的是,Scala没有针对无限类型的定点组合器)。我们称之为InfCurry,它看起来像这样:

trait InfCurry[T] extends (T => InfCurry[T])

正如您所看到的,它很好地模仿了上面的定义(另一种选择是类型别名,但Scala不支持递归类型别名)。

让我们定义一个构造函数方法来帮助我们定义我们无限的curried函数:

object InfCurry {
  def apply[T](f: T => InfCurry[T]): InfCurry[T] = new InfCurry[T] {
    def apply(x: T) = f(x)
  }
}

使用这个小工具,你可以定义这样的东西:

val f: InfCurry[Int] = InfCurry { x =>
  println(x)
  f
}

你会用这样的小东西:

val g = f(1)(2)(3)(4)(5)(6)(7)
g(8)(9)(10)(11)(12)

在这种情况下,您可能希望使用具有可变数量参数的方法 - 请参阅另一个答案 - 但这就是您的要求。