Scala curry在trait同伴对象中的应用

Scala curry在trait同伴对象中的应用,scala,Scala,两个问题: 1) 为什么当apply函数是curry函数时,我不能在BaseTrait伴随对象中使用这两个apply方法(注意,当它们是非curry函数时,它会起作用,带有两个参数) 2) 我如何实现这一功能:多个套用的方法 trait BaseTrait[T, U] { def name: String def tryMe(record: T): Option[U] } object BaseTrait { // can't have both apply methods whe

两个问题:

1) 为什么当
apply
函数是curry函数时,我不能在
BaseTrait
伴随对象中使用这两个
apply
方法(注意,当它们是非curry函数时,它会起作用,带有两个参数)

2) 我如何实现这一功能:多个套用的方法

trait BaseTrait[T, U] {
  def name: String
  def tryMe(record: T): Option[U]
}

object BaseTrait {
  // can't have both apply methods when curried
  def apply[T](s: String)(f: T => Option[Long]): LongTrait[T] =
    new LongTrait[T] {
      override val name: String = s
      override def tryMe(record: T): Option[Long] = f(record)
    }

  def apply[T](s: String)(f: T => Option[Boolean]): BooleanTrait[T] =
    new BooleanTrait[T] {
      override val name: String = s
      override def tryMe(record: T): Option[Boolean] = f(record)
    }
}

trait LongTrait[T] extends BaseTrait[T, Long] {
  override def tryMe(record: T): Option[Long]
}

trait BooleanTrait[T] extends BaseTrait[T, Boolean] {
  override def tryMe(record: T): Option[Boolean]
}
它可以正常编译,但会引发运行时错误:

scala> BaseTrait("test") { s: String => Option(s.toBoolean) }

<console>:13: error: ambiguous reference to overloaded definition,
both method apply in object BaseTrait of type [T](s: String)(f: T => 
Option[Boolean])BooleanTrait[T]
and  method apply in object BaseTrait of type [T](s: String)(f: T => 
Option[Long])LongTrait[T]
match argument types (String)
   BaseTrait("test") { s: String => Option(s.toBoolean) }
scala>BaseTrait(“测试”){s:String=>Option(s.toBoolean)}
:13:错误:对重载定义的引用不明确,
这两种方法都适用于类型为[T](s:String)(f:T=>
选项[Boolean])布尔特征[T]
和方法应用于类型为[T](s:String)(f:T=>
选项[Long])LongTrait[T]
匹配参数类型(字符串)
BaseTrait(“test”){s:String=>Option(s.toBoolean)}

如果颠倒当前参数的顺序,使它们在第一个参数中有所不同,则可以成功调用apply方法

object BaseTrait {
    // can't have both apply methods when curried
    def apply[T](f: T => Option[Long])(s: String): LongTrait[T] =
      new LongTrait[T] {
        override val name: String = s
        override def tryMe(record: T): Option[Long] = f(record)
      }

    def apply[T](f: T => Option[Boolean])(s:String): BooleanTrait[T] =
      new BooleanTrait[T] {
        override val name: String = s
        override def tryMe(record: T): Option[Boolean] = f(record)
      }
  } 

BaseTrait { s:String => Option(s.toBoolean) }("test") 
res58: BooleanTrait[String] = ammonite.$sess.cmd57$BaseTrait$$anon$2@e39317d
如评论中所述。在被引用的问题中(该问题以“惯常修复”状态结束),下面的简单代码也显示了相同的模糊引用问题

object Foo {
  def bar(i: Int) = println(i)
  def bar(i: Int) (f: Float) = println(i*f)
}
根据Scala语言创作者Martin Odersky的说法

“我刚才在上面写道,规范中没有尝试做这样的事情。我向您提出挑战,请您提供一套完整且可确定的规则来完成此操作。”


因此,由于难以实施必要的检查,因此不可能阻止这些方法编译,即使它们随后无法被引用。

我认为,它编译的是一个bug。这不应该。@Dima你能详细说明一下吗?Scala编译器是否能够区分b/w Function1[T,Option[Boolean]]和Function1[T,Option[Long]],但编译的Java代码却不能?如果你有更多的细节,我很好奇。谢谢你给我指出这个问题!遗憾的是没有解决方案(除了交换方法的第一部分)。