【问题标题】:Defining a method whose return type is the singleton type of an argument of that method定义一个方法,其返回类型是该方法的参数的单例类型
【发布时间】:2011-04-07 00:57:00
【问题描述】:

仍在为 this.types(单例类型)而苦苦挣扎。假设这种情况:

trait Sys[A <: Access] {
  def in[T](v: String): AccessPrepare[A]
}

trait AccessPrepare[A <: Access] {
  val a: A
  def apply[T](fun: a.type => T): T
}

object Ref {
  def single[A <: Access, V](v: V)(implicit a: A): Ref[A, V] = ???
}
trait Ref[A, V]

trait Access {
  def set(r: Ref[this.type, Int]): Unit
}

以下失败:

def test(sys: Sys[Access]): Unit =
  sys.in("v1") { implicit a =>
    val r = Ref.single(44)
    a.set(r)
  }

因为显然r 的类型是Ref[Access, Int] 而不是Ref[a.type, Int]。我的猜测是问题是我需要像这样的一行

def single[A <: Access, V](v: V)(implicit a: A): Ref[a.type, V] = ...

由于“非法依赖方法类型”而无法编译...

任何想法我可以解决这个问题。要求是我没有用类型明确地注释调用。也就是说,出于可以理解的原因,我确实不想Ref.single[a.type, Int](44)(a)


编辑

作为澄清,参考线程 Constraining an operation by matching a type parameter to an argument's path-dependent type 中的回答“仅供参考,并关闭问题”——我还想拥有不使用工厂方法创建对象(Refs)的可能性访问但在外部某处(例如,使用new 语句)。因为系统不受 Access 定义的限制,所以我必须能够用更多的对象来扩展它。

【问题讨论】:

标签: scala types singleton


【解决方案1】:

你有几种可能性。使用 Scala 2.8/2.8.1,您可以使用私有选项 -Ydependent-method-types,然后使用您的解决方案

def single[ A <: Access, V ]( v: V )( implicit a: A ) : Ref[ a.type, V ] = // ...

编译正常。

如果您想避免依赖方法类型,因为它是一个私有选项,您仍然可以通过显式键入对 Ref.single 的调用来编译您的第一个提案:

  val r = Ref.single[a.type, Int](44)

但是,您需要指定类型,因为永远不会推断出单例类型。您的问题与未推断单例类型的问题不同但与之相关:请参阅How to correctly type-annotate this HList?

【讨论】:

  • 太好了,非常感谢。我第一次听到依赖方法类型选项。所以类型系统可以处理它。我想知道这是否会在未来的 Scala 版本中被激活或公开?
猜你喜欢
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
相关资源
最近更新 更多