Scala:带有两个参数列表的函数对象的类型是什么?

时间:2015-02-03 22:19:44

标签: scala types implicit higher-order-functions

假设我想将一个带有两个参数列表的函数对象作为高阶函数的参数传递。这种物体的类型是什么?

例如,这可能是这样一个对象:

object passMe extends <???> {
    def apply(x: Double)(implicit ctx: Context): String = . . .
}

extends之后我应该放什么?或者我如何声明一个接受passMe作为参数的函数?

def foundation(xs: Seq[Double], oneOfThoseObjects: <???>)(implicit ctx: Context): Unit = {
  . . .
  xs.map(oneOfThoseObjects).toSet. . . .
}

我的示例使用隐式参数列表,因为这主要是我感兴趣的内容,但它仍然有助于知道如何使用两个显式参数列表声明一个函数。我还没有在Function1,Function2,...系列中找到任何可以表明这样的声明的样子。

2 个答案:

答案 0 :(得分:2)

具有两个参数列表的函数可以建模为返回另一个函数的函数。这是一种名为currying的技术。例如,添加函数可以这样写:

scala> val add:Function1[Int,Function1[Int, Int]] = x => (y => x + y)
add: Int => (Int => Int) = <function1>

并且这样称呼:

scala> add(1)(2)
res1: Int = 3

如您所见,可以使用Function1=>语法编写相同的类型。

答案 1 :(得分:1)

在REPL中玩了一些游戏之后,我来到了这里:

(Double => (Context => String))

其中,用英语说,“函数采用double并返回一个带上下文并返回字符串的函数”

因此,您的passMe对象看起来像这样:

object passMe extends (Double => (Context => String)) {
  def apply(d: Double) = {
    def f(c: Context) = "...something..."
    f _
  }
}

但是,由于隐式参数,这不起作用,因为使用隐式参数,最终会出现类型不匹配(需要scala.collection.immutable.WrappedString)。所以我最终得到了这个:

object passMe extends (Double => scala.collection.immutable.WrappedString) {
  def apply(d: Double) = {
    def f(implicit c: Context) = "...something..."
    f _
  }
}