2016-09-23 5 views
3

は、なぜ私は、次のことが可能です。エイリアシング適切な型(?なぜそれがコンパイルされます)

class A 
type M[_] = A 

私は、私は1つの型パラメータを期待するだけエイリアスタイプ、例えば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

2番目の質問には、 'クラスA [T <:AnyRef、U <:AnyVal]'と 'タイプM = A [_、_]'がありますか? – Samar

+0

@Samarこれは非常に異なる状況です。 –

答えて

3

type M[_] = Aは、type M[X] = Aと同じです。タイプには一定の機能があります。 M[X]は何XAある:M[Int]など、M[String]Aで、AあるM[Any]Aあり、この場合には、_(ならびにtype M[_, _]のエラーを説明する)だけの識別子です。

もちろん、def foo(m: M[_]) = mでは、M[_]M[T] forSome { type T }という実在のタイプです。私はなぜScalaがそれがエラーメッセージのA[]に拡大すると言うのか分からない。これはバグかもしれません。あなたは

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

私は私のエイリアスの右側に置くものをパラメータ化タイプになることを保証する方法はありますを呼び出すことによって、それはAと同じタイプだ確認することができますか?

あなたは、より高い種類

trait Foo { type M[_] } 

と抽象メンバーの型を宣言することができ、それが唯一のパラメータ化のタイプによって実装することができます:最初の段落で述べたように、もちろん

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

M in type M[X] = Intです。私はそれを排除する方法はないと思います。

+0

スカラ型システムの理解に専念する大学はありますか?どうすれば参加できますか? – Samar

関連する問題