2016-06-26 9 views
5

私はいつも型エイリアスが必要ならば元の型に常に拡張すると信じていました。しかし、ここではそれはあなたがbがそれを呼び出すときb用品Some[V]aOption[V] => List[V]を変換するのでaは、Option[P] => List[P]を変換していることがわかり(scastieスカラ型のエイリアシングは型の互換性を損なう

error: type mismatch; 
found : Res (which expands to) List[P] 
required: List[V] 

で失敗したトラブル

def a[P](a: Option[P]) = { 
    type Res = List[P] // result type alias 
    Nil: Res // Replace this line with Nil: List[P] to clear the error 
} 
def b[V](v: V) = a(Some(v)): List[V] 

です。しかし、結果はList[V]と互換性がありません。これはどのように可能ですか? Nil: ResaNil: List[P]に置き換えると、エラー(scastie)がなくなります。エラーを取り除くには、エイリアスを削除する必要があります。これは、型エイリアスが原因であることを意味します。

+1

たとえそれがコンパイラのバグであっても、メソッドの中で型エイリアスを宣言し、その型を返すのは奇妙で混乱します。 –

+0

@ m-z私は[引数を解析するrecurion](http://stackoverflow.com/questions/38037089)でそれを使用しました。それは間違っているとあなたはもっと良い方法を知っている。実際、これはOderkiのCoruseraコースによって推進されるプログラミングスタイルです。彼らはfoldLeftをやっていないと、あなたは再帰を行うことを教えてくれました。再帰は、プロビジョニングされたデザインスペースを繰り返す特別な手段がなければ、すべてを行うことができます。再帰は、ファサード関数を持っていることを意味します。ファサード関数はユーザからの呼び出しを受け入れますが、実際の実装は '内部'再帰関数によって行われます。 –

+0

つまり、基本的な機能パターンは 'def facade(args)= {def worker(反復、アキュムレータ:ResType)です:ResType = if(done)acc else {.recursion。};あなたが見るように、ワーカーの 'acc'は結果の型にマッチし、あなたはScalaでワーカーの結果型を宣言しなければなりません。つまり、ファサードをコーディングするときに結果のタイプを2回指定する必要があります。この最も基本的なFPパターンではDRYの後にそれが間違っていることを表示し、悪いプログラミング方法から私たちを救うために、downvoteしてください。その労働者は外に宣言しなければならないと言います。内部からの型の悪い匂いだと言います。 –

答えて

0

これはコンパイラのバグです。 Scalaの型エイリアスは自動的に展開されるはずですが、この場合、[P](Option[P]) => List[P]の代わりにの型が[P](Option[P]) => Resと推定されます。また、Resが内部スコープ内にあるため、コンパイラはbの型を正しく推測することができません。

関連する問題