Scala重载函数来添加咖喱?

Scala重载函数来添加咖喱?,scala,currying,Scala,Currying,今天开始学习Scala,我很好奇是否可以重载一个函数来添加咖喱: def add(x: Int, y: Int): Int = x + y def add(x: Int)(y: Int): Int = x + y 但这段代码不仅不能编译,而且我听说在Scala中重载不是一个好主意 有没有一种方法可以重载add,使其在不执行部分应用程序的情况下运行,这意味着add(1,2)和add(1)(2)都可以工作?对于重载,函数必须: 有不同数量的参数 或具有不同的参数类型 在您的示例中,add的两个

今天开始学习Scala,我很好奇是否可以重载一个函数来添加咖喱:

def add(x: Int, y: Int): Int = x + y
def add(x: Int)(y: Int): Int = x + y
但这段代码不仅不能编译,而且我听说在Scala中重载不是一个好主意


有没有一种方法可以重载add,使其在不执行部分应用程序的情况下运行,这意味着
add(1,2)
add(1)(2)
都可以工作?

对于重载,函数必须:

  • 有不同数量的参数
  • 或具有不同的参数类型
在您的示例中,
add
的两个定义都是等效的,因此它没有重载,您会得到编译错误

您可以使用下面的Kolmar方法(
隐式
对象)调用
add(1,2)
add(1)(2)
,或者您可以使用Scala实现相同的功能:

def add(a: Int, b: Int, c: Any = DummyImplicit) = a + b // c is default parameter
def add(a: Int)(b: Int) = a + b
关于:

我听说Scala中的重载不是一个好主意


你可以看到

我有一种方法可以使用add(1,2)和add(1)(2),但我不推荐。它使用Scala的隐式定义为这两种方法提供不同的类型,但使用隐式方法转换为适当的类型

case class IntWrapper(value: Int) // Purely to have a different type

object CurryingThing
{
  def add(x: IntWrapper)(y: IntWrapper) = x.value + y.value
  def add(x: Int, y: Int) = x + y

  // The magic happens here. In the event that you have an int, but the function requires an intWrapper (our first function definition), Scala will invoke this implicit method to convert it
  implicit def toWrapper(x: Int) = IntWrapper(x)

  def main(args: Array[String]) = {
   // Now you can use both add(1,2) and add(1)(2) and the appropriate function is called
   println(add(1,2)) //Compiles, prints 3
   println(add(1)(2)) // Compiles, prints 3
   ()
  }
}

问题是,在JVM类型擦除之后,这些
add
函数无法区分:在执行过程中,它们都是
(Int,Int)Int
。但在编译过程中它们是不同的,Scala编译器可以告诉您调用的是哪一个

这意味着你必须使他们的论点列表不同。要实现这一点,可以添加带有
DummyImplicit
参数的隐式参数列表:

def add(x: Int, y: Int)(implicit dummy: DummyImplicit): Int = x + y
def add(x: Int)(y: Int): Int = x + y
这个
DummyImplicit
是由Scala库提供的,它总是有一个隐式值。现在,擦除后的第一个函数的类型是
(Int,Int,DummyImplicit)Int
,第二个函数的类型是
(Int,Int)Int
,因此JVM可以区分它们

现在,您可以同时调用这两个:

add(1, 2)
add(1)(2)

但是,我怎样才能实现我的提议呢?所以我可以打电话给add(1,2)和add(1)(2)。很抱歉进行了编辑,我担心是否有一种方法可以同时使用
add(1,2)
add(1)(2)
。啊,好的,不用担心。我只是好奇这是否可能。谢谢你花时间回答。这很酷,但我觉得有点太老套了,不太实际。谢谢