[英]Curried apply in trait companion object
Two questions: 两个问题:
1) Why am I unable to have these two apply
methods in the BaseTrait
companion object when the apply
functions are curried (note, it works when they are un-curried, with two arguments)? 1)当
apply
函数被咖喱化时,为什么我不能在BaseTrait
伴随对象中拥有这两个apply
方法(注意,当它们被非咖喱化时,带有两个参数,它可以工作)?
2) How can I achieve this functionality: multiple apply methods that are curried? 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]
}
It compiles fine, but throws a runtime error: 它可以正常编译,但是会引发运行时错误:
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) }
If you reverse the order of the current arguments, such that they differ in the first argument, then the apply method can be invoked successfully. 如果您颠倒当前参数的顺序,以使它们在第一个参数中不同,则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
As mentioned in the comment, this appears to be a corner case in the language . 如评论中所述, 这似乎是该语言的一个极端案例 。 In the referenced issue, which was closed with a Wont-Fix status, the following simpler code also exhibits the same ambiguous reference issue.
在以“ Wont-Fix”状态关闭的引用问题中,以下更简单的代码也表现出相同的歧义引用问题。
object Foo {
def bar(i: Int) = println(i)
def bar(i: Int) (f: Float) = println(i*f)
}
According to Scala language creator Martin Odersky, 根据Scala语言创建者Martin Odersky的说法,
"I just wrote above that there is no attempt to do such a thing in the spec. I challenge you to give a set of complete and decidable rules to do this." “我只是在上面写道,规范中没有尝试做这样的事情。我向您挑战,请您提供一套完整且可确定的规则来做到这一点。”
So it appears that due to the difficulty of implementing the necessary checks, it is not possible prevent these methods from compiling even though they cannot be subsequently referenced. 因此看来,由于难以实施必要的检查,因此即使无法随后引用这些方法,也无法阻止这些方法的编译。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.