2

この構文で無制限のパラメータを取得できる関数を書きたい

myfunc arg1 arg2 arg3 .... curring を使用していくつか試してみましたが、再帰的に作成しようとしても何の助けにもなりませんでしたが、scala コンパイラは次のように述べています:「scala 再帰メソッドには結果型が必要です」 再帰:

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

ヘルパーに感謝

4

2 に答える 2

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}
于 2013-03-28T16:07:59.533 に答える
6

したがって、求める関数は特定の型の引数を取り、同じ型の引数を取り、同じ型の引数を取る関数を返す関数を返さなければなりません。

ここでの問題は、この関数の型が次の行にあることです。

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

つまり、再帰的な自己参照型です。それは自己参照であるため、それ自体の中で再利用するという唯一の目的で名前を付ける必要があります (残念ながら、Scala には無限型の固定小数点コンビネーターがありません)。それを呼び出してみましょう。次のようにInfCurryなります。

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

ご覧のとおり、上記の定義を非常によく模倣しています (別のオプションは型エイリアスでしたが、Scala は再帰的な型エイリアスをサポートしていません)。

無限にカリー化された関数を定義するのに役立つコンストラクター メソッドも定義しましょう。

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)

おそらくこの場合、可変数の引数でメソッドを使用したいと思います-他の回答を参照してください-しかし、これはあなたが求めたものです。

于 2013-03-28T17:39:57.693 に答える