2011-04-07 41 views
2

仍在挣扎着使用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) 
    } 

因为很显然rRef[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)是为了便于理解。


编辑

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

+0

我又增加了一个问题:http://stackoverflow.com/questions/5575030/driving-a-singleton-type - 我认为如果我能解决这个问题,这个问题也将因此而得到解决(我希望) – 2011-04-07 01:52:30

回答

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?

+0

非常好,非常感谢。我第一次听到依赖方法类型选项。所以类型系统_can_可以处理它。我想知道这将在未来的Scala版本中被激活或公开吗? – 2011-04-11 00:04:18