在Scala中,假设我有这样的函数:
def foo[R](x: String, y: () => R): R
所以我可以这样做:
val some: Int = foo("bar", { () => 13 })
有没有办法改变这个以使用函数currying而不“丢失”第二个参数的类型?
def foo[R](x: String)(y: () => R): R
val bar = foo("bar") <-- this is now of type (() => Nothing)
val some: Int = bar(() => 13) <-- doesn't work
答案 0 :(得分:14)
函数不能有类型参数,你必须使用这样的自定义类:
def foo(x: String) = new {
def apply[R](y: () => R): R = y()
}
val bar = foo("bar")
val some: Int = bar(() => 13)
// Int = 13
为了避免结构类型,您可以明确地创建自定义类:
def foo(x: String) = new MyClass...
答案 1 :(得分:7)
对senia答案的一种变体,以避免结构类型:
case class foo(x: String) extends AnyVal {
def apply[R](y: () => R): R = y()
}
val bar = foo("bar")
val some: Int = bar(() => 13)
// Int = 13
答案 2 :(得分:2)
并非真正解决您的问题,只是指出如果明确提供类型,您仍然可以使用函数的第二个版本:
scala> def foo[R](x: String)(y: () => R): R = y()
foo: [R](x: String)(y: () => R)R
scala> val bar = foo[Int]("bar") _
bar: (() => Int) => Int = <function1>
scala> bar(() => 12)
res1: Int = 12