2

我想定义一个带有一个显式和一个隐式参数的函数,如下所示:

def foo(a: Int)(implicit b: Int) : Int

但作为一个类或对象,像这样

object Foo extends ((Int,Int) => Int) {
  def apply(a: Int)(implicit b: Int) : Int = { ... }
}

以便可以像这样调用该函数:

implicit val b = 2
val g = Foo(1)

我没有得到类Foo应该正确扩展的基的声明。如何才能做到这一点?

4

4 回答 4

5

你不能。Function2[T1, T2, R]声明了抽象方法apply(t1: T1, t2: T2): R,所以如果你想混入Function2,你必须实现这个 arity-2 apply方法,它有不同的签名比你想使用的咖喱版本。

于 2012-04-24T09:37:32.940 回答
0

所以这个问题有两个部分——首先,如何创建一个对象来实现一个带有柯里化参数列表的函数。然后,如何使这些参数列表之一隐含。

其中第一个绝对是可能的。请注意,柯里化函数是返回函数的函数。所以f(x: Int)(y: Int)实际上是 a Function1,而不是 a Function2

scala> def f(x: Int)(y: Int) = x + y
f: (x: Int)(y: Int)Int

scala> f _
res0: Int => Int => Int = <function1>

你当然可以创建一个实现这个的类:

scala> object Foo extends (Int => Int => Int) {
     |   def apply(x: Int) = {(y: Int) => x + y}
     | }
defined module Foo

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

不幸的是,我不知道有任何方法可以使第二个参数列表隐式。

于 2012-04-24T14:04:36.260 回答
0

一个问题是:为什么您必须将该对象 Foo 传递给“期望 (Int,Int) => Int 的地方”?

我想对象 Foo 应该有一些更特殊的功能,这些功能会增强它的功能吗?

在这里分开两个问题似乎更好:a)函数(Int)(隐式Int)=> Int和b)对象Foo

object Foo {
  def apply(a: Int, b: Int) : Int = { ... }
}

def foo(a: Int)(implicit b: Int) : Int = Foo(a, b)

implicit val m:Int = 42

foo(5)  // --> res1: Int = 47

如果您愿意,您可以将 'foo' 视为“伴随功能”...

除此之外:我想尝试应用 (Int)(implicit Int)=>Int “其中需要 (Int,Int) => Int”可能不起作用,因为这些类型并不相同。至少当您尝试将其放入

def bar(f:(Int,Int)=>Int) = ....

方法 bar 无论如何都会用两个参数调用它的参数 f ,因为它希望它接受两个参数,并且不能假设 f 中提供的函数确实能够使用隐式。

于 2012-04-24T15:29:28.477 回答
0

(Int, Int) => Int您可以使用隐式转换,而不是扩展:

class Foo(f: (Int, Int) => Int) {
  def apply(a: Int)(implicit b: Int) : Int = f(a, b)
}

implicit def Foo_to_Function2(foo: Foo) = (x: Int, y: Int) => foo(x)(y)

测试:

val foo = new Foo(_ * 10 + _)
foo(4) //error since no implicit Int yet
{
  implicit val impint = 5
  foo(4)  //45
}  
def takesF2(f: (Int, Int) => Int) = f(1, 2)
takesF2(foo)  //12 - works as normal Function2
于 2012-04-24T14:13:29.287 回答