2015-09-16 95 views
2

我有以下特点(简化的例子)参数化类型界限

trait F[A, M[_] <: Option[A]] { 

    def v: A 

    def f: A => M[A] 

} 

我希望能够创建以下特点

trait G[A] extends F[A, Some] 

但是,这提供了以下错误

Error:(18, 20) type arguments [A,Some] do not conform to trait F's type parameter bounds [A,M[_] <: Option[A]]

如何限制M[_]段计量型?

编辑:

A型F[A, M[_] <: Option[_]]会工作。但其实我有另一个功能在我的特质

trait F[A, M[_] <: Option[_]] { 

    def v: A 

    def f: A => M[A] 

    def f2: A => A = { 
    (a: A) => f(a).get 
    } 

} 

,并在f2这种情况下,get不返回类型的值A即使f回报M[A]

Error:(17, 20) type mismatch; 
found : _$1 
required: A 
    (a: A) => f(a).get 
+0

你能改变M [_]到M [A]吗? –

+0

感谢Rich,将'M [_]'改为'M [A]'实际上正在工作。 – synapski

回答

0

您可以完全约束M的类型,因为它不需要采取类型参数:

trait F[A, M <: Option[A]] { // M no longer takes a type parameter 
    def v: A 
    def f: A => M 
    } 

    trait G[A] extends F[A, Some[A]] // Must specify M[A] since M doesn't take a type parameter 

然而,你可能需要提供某种映射机制或东西,去一些其他类型的M[B]在这种情况下,限制较少的版本会更好的工作:

trait F[A, M[_] <: Option[_]] { // M is no longer constrained to A 
    def v: A 
    def f: A => M[A] // M is manually constrained to A here 
    } 

    trait G[A] extends F[A, Some] 

UPDATE

很遗憾,您f2功能将无法工作。尽管我们知道这些类型是正确的,但编译器无法正确推断出类型(Scala的限制)。您可以将此功能添加到G[A],它将按预期工作,因为M[_]现在具有一个具体的类型。

trait G[A] extends F[A, Some]{ 
    def f3: A => A = a => f(a).get 
    } 

而作为一个侧面说明,你不应该使用Option.get,它失去了使用的Option的宗旨! flatMap它或东西:)

+0

谢谢诺亚。我编辑了这个问题来匹配我的用例。 'F [A,M [_] <:Option [_]]'是我想要的,但我无法在我新定义的函数中获得正确的类型。 – synapski

+0

@synapski更新了答案 – Noah