2015-09-16 121 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