2016-09-23 62 views
3

我爲什麼可以做以下(爲什麼它編譯):走樣適當類型爲生存型

class A 
type M[_] = A 

我希望我只能別名類型的期望一種類型的參數,例如List[_],但它也適用於普通課程。

如果我創建了一個方法:

def foo(m: M[_]) = m 

,並用錯誤的參數調用它:

scala> foo("a") 
<console>:15: error: type mismatch; 
found : String("a") 
required: M[_] 
    (which expands to) A[] 
     foo("a") 

我得到這樣的錯誤。 A[]是什麼意思?

的進一步深入,這怎麼解釋:

scala> type M[_, _] = A 
<console>:12: error: _ is already defined as type _ 
     type M[_, _] = A 

有沒有一種方法,以確保我把我的別名的右側將是一個參數化類型?

+0

你的第二個問題:是'A類[T <:AnyRef,U <:AnyVal]'&'類型M = A [_,_]'你想要什麼? – Samar

+0

@Samar這是一個非常不同的情況。 –

回答

3

type M[_] = Atype M[X] = A相同:類型的常量函數。 M[X]A任何X是:M[Int]AM[String]AM[Any]A_在這種情況下僅僅是一個標識符(這可以解釋爲type M[_, _]誤差以及)。

當然,在def foo(m: M[_]) = mM[_]是一個存在類型:M[T] forSome { type T }。我不知道爲什麼Scala在錯誤信息中將它擴展爲A[],這可能是一個錯誤。你可以檢查它的類型相同A通過調用

scala> implicitly[M[_] =:= A] 
res0: =:=[A[],A] = <function1> 

有沒有一種方法,以確保我把我的別名的右側將是一個參數化類型?

你可以聲明具有較高的實物

trait Foo { type M[_] } 

一個抽象成員類型,它只能通過參數化類型來實現:

class Bar1 extends Foo { type M = Int } // fails 
class Bar2 extends Foo { type M[X] = List[X] } // works 

當然,作爲第一款所列,Mtype M[X] = Int參數化,我不認爲有一種方法可以排除它。

+0

有沒有一個致力於理解scala類型系統的大學?我如何加入? – Samar