仍在与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中的回答“FYI,并关闭问题” - 我想要的另外一点是创建对象(Refs)的可能性不是通过使用访问中的工厂方法但在某处外部(例如,使用new
语句)。由于系统不受Access定义的限制,我必须能够使用更多对象扩展它。
答案 0 :(得分: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?