使用 Scala 2.10 和无形:
import shapeless.Nat._
import shapeless.{Nat, Succ}
trait Curry[T, Res, N <: Nat] {
type Out
def apply(as: Seq[T], f : Seq[T] => Res) : Out
}
object Curry {
implicit def curry[Out0, T, Res, N <: Nat](implicit curry : CurryAux[Out0, T, Res, N]) = new Curry[T, Res, N] {
type Out = Out0
def apply(as: Seq[T], f : Seq[T] => Res) = curry(as, f)
}
}
trait CurryAux[Out, T, Res, N <: Nat] {
def apply(as: Seq[T], f : Seq[T] => Res) : Out
}
object CurryAux {
implicit def curry0[Res, T] = new CurryAux[Res, T, Res, _0] {
def apply(as: Seq[T], f : Seq[T] => Res) : Res = f(as)
}
implicit def curryN[Out, T, Res, N <: Nat](implicit c : CurryAux[Out, T, Res, N]) =
new CurryAux[T => Out, T, Res, Succ[N]] {
def apply(as: Seq[T], f : Seq[T] => Res) : (T => Out) = (a: T) => c(as :+ a, f)
}
}
implicit class CurryHelper[T, Res](f : Seq[T] => Res) {
def curry[N <: Nat](implicit c : Curry[T, Res, N]): c.Out = c(IndexedSeq[T](), f)
}
用法:
scala> def concat(strs: String*) = strs.mkString
concat: (strs: String*)String
scala> val test = ( concat _ ).curry[_3]
test: String => (String => (String => String)) = <function1>
scala> test("1")("2")("3")
res0: String = 123
没有无形:
class CurryHelper[T, Res](f: Seq[T] => Res, as: Seq[T]) {
def myCurry() = this
def apply(ts: T*) = new CurryHelper(f, as ++ ts)
def apply(ts: Seq[T]) = f(as ++ ts)
}
implicit def toCurryHelper[T, Res](f: Seq[T] => Res) = new CurryHelper(f, IndexedSeq[T]())
scala> def concat(strs: String*) = strs.mkString
concat: (strs: String*)String
scala> val test = ( concat _ ).myCurry
test: CurryHelper[String,String] = CurryHelper@4f48ed35
scala> test("1")("2")("3", "4")(Nil)
res0: String = 1234