Scala中的类型函数和Currying

rei*_*kje 9 scala

在Scala中,假设我有这样的函数:

def foo[R](x: String, y: () => R): R
Run Code Online (Sandbox Code Playgroud)

所以我可以这样做:

val some: Int = foo("bar", { () => 13 })
Run Code Online (Sandbox Code Playgroud)

有没有办法改变这个使用函数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
Run Code Online (Sandbox Code Playgroud)

sen*_*nia 14

函数不能有类型参数,你必须使用这样的自定义类:

def foo(x: String) = new {
  def apply[R](y: () => R): R = y()
}

val bar = foo("bar")
val some: Int = bar(() => 13)
// Int = 13
Run Code Online (Sandbox Code Playgroud)

要避免结构类型,您可以显式创建自定义类:

def foo(x: String) = new MyClass...
Run Code Online (Sandbox Code Playgroud)


Kev*_*ght 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
Run Code Online (Sandbox Code Playgroud)