首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Curried在特征伴生对象中应用

Curried在特征伴生对象中应用
EN

Stack Overflow用户
提问于 2017-12-16 09:54:35
回答 1查看 50关注 0票数 2

两个问题:

1)为什么在BaseTrait函数中不能包含这两个apply方法(注意,当它们使用两个参数取消执行时,它是有效的)?

2)我怎样才能实现这个功能:多个应用方法是curried的?

代码语言:javascript
复制
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]
}

它编译得很好,但抛出了一个运行时错误:

代码语言:javascript
复制
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) }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-16 11:14:55

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

代码语言:javascript
复制
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

正如评论中提到的,this appears to be a corner case in the language。在引用的问题中,以习惯修复状态关闭,以下更简单的代码也显示了相同的模糊引用问题。

代码语言:javascript
复制
object Foo {
  def bar(i: Int) = println(i)
  def bar(i: Int) (f: Float) = println(i*f)
}

根据Scala语言的创建者Martin Odersky的说法,

“我刚刚在上面写过,在规范中没有这样做的企图。我挑战你给出一套完整的和可决定的规则来做到这一点。”

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47841866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档