2016-09-22 11 views
2

私はtoBarList関数がコンパイルされません。このコードScalaの暗黙のコンパイルエラー

case class Foo(x: Int) 
case class Bar(y: Int) 
object Foo { 
    implicit def toBar(f: Foo) : Bar = { Bar(f.x) } 
    implicit def toBarList(fl: List[Foo]) : List[Bar] = {fl.map{x: Bar => x}} 

を書きました。

<console>:17: error: type mismatch; 
found : Bar => Bar 
required: Foo => ? 
     implicit def toBarList(fl : List[Foo]) : List[Bar] = { fl.map{x : Bar => x}} 

ここではimplicitsシステムを使用しないでください。コンパイラは、関数がBarを期待しているがFooを渡しているというエラーがあることを検出する必要があります。今ではFooをBarに変換するスコープ内の暗黙的な関数が既に存在しているので、これを使用する必要があります。

なぜ、これはコンパイルされませんでしたか?

+0

、 '{fl.map {X:バー=> B}}'、おそらくあなたは意味 '{fl.map {X: Bar => x}} 'または' {fl.map {b:Bar => b}} 'のようになります。 – dveim

答えて

2

mapは、関数引数をとる通常の方法であり、List[Foo]mapは、関数がFooである必要があります。 Bar(具体的にはBar => Bar)の機能を提供していますが、暗黙的な変換をFooからBarに変更しても、Bar => BarからFoo => Barのいずれかになります(この方法では必要です)。

あなたはこれが仕事をしたい場合は、(明示的または暗黙的に)Fooから機能を提供して、変換を適用する必要がありますか、あなたはBar => BarからFoo => Barに暗黙の型変換を提供する必要があります(と類似List[Foo]からList[Bar]に変換しようとしていますが、Function1は最初の引数に反変で、Listは共変です。最初のスニペットで

(これはしかし、すべての非常に悪い考えです。)

+0

私の無知。コンパイラがFoo => Barを提供しているが、Bar => Barが必要であることを発見したとき。なぜそれが暗黙のために、Foo to Barの変換を自動的に入れないのでしょうか?したがって、コンパイラは、Foo => Bar変換をBar => Bar変換に変換する必要があります。これは、Foo => Bar変換がスコープ内にあるためです。 –

+0

@KnowsNotMuch理由の核心は、関数が特定のクラスのインスタンス(何らかの特殊な構文を持つことがある)にすぎないということです。この点に関して特別なケースはありません。もしあなたが 'Foo => Bar'を必要とし、' Bar => Bar'を持っているなら、 'Foo'から' Bar'への変換はあなたを助けません'List [Foo]'を持っていて 'List [Bar]'が必要な場合に役立ちます)。 –

関連する問題