2017-01-30 14 views
0

は考える:`暗黙のdef`を暗黙的に定義していますか?

trait Foo[A] 
class B 

し、次のimplicit def

implicit def f[A](b: B)(implicit ev: Foo[A]): String = "foo" 

私は暗黙のうちにB => Stringを解決しようとしましたが、それはコンパイルに失敗しました:

scala> implicitly[B => String] 
<console>:15: error: No implicit view available from B => String. 
     implicitly[B => String] 
       ^

私は推測していますimplicit Foo[A]はレンチを投げているので、言い換えれば暗黙的な解像度はB => Stringです。

上記のように、implicitlyの引数i..e B => Stringを調整するにはどうすればよいですか?

+1

暗黙的に[Foo [B]](あなたの暗黙の変換の前提条件)の前に試したことがありますか? – cchantep

+0

それは良い点です - 私の間違い。 –

+1

BTW '暗黙のA => B'は、型付きではなく暗黙の変換であり、対応する警告につながります(コードがすばやく混乱する可能性があるため)。むしろ '特性MyFunT [A] extends(A => String)'を使うでしょう。 – cchantep

答えて

1

むしろ暗黙の型変換よりも型クラス使って同様のコード:

trait MyFunT[A] extends (A => String) 

object MyFunT { 
    /**Factory to easily define an instance from a fun */ 
    def apply[A](f: A => String): MyFunT[A] = new MyFunT[A] { 
    def apply(a: A): String = f(a) 
    } 
} 

implicit def foo[A](implicit ev: Foo[A]) = MyFunT[A] { a: A => /* do something with `a` and `ev` */ "foo" } 

implicitを必要と/ベースimplicit sが通常の場合でも、私はそのことについて、「あまりにも長鎖」を持っていないように注意してくださいへのアドバイスです。

+0

'object Foo'に次の関数を追加するのも良い選択でしょうか?' def instance [A](f:A => Foo [A]):Foo [A] '?私は[Shapeless Guide](https://github.com/underscoreio/shapeless-guide)を再読み込みした後、この質問をしました。ここでは、 'CsvEncoder'のtypeclassについて言及しています:https://github.com/kevinmeredith/shapeless_book_exercises/ blob/master/src/main/scala/net/CsvEncoder.scala#L12-L15。 –

+1

このようなファクトリ関数は、サンプル – cchantep

+0

のように 'apply'と呼ばれることがあります。役に立つ答えとコメントを読んだ後、' MyFunT'を '(A => String)'に拡張するのがなぜ有用かわかりません。もしあなたがその継承を取り除くと、何が失われるのでしょうか? –

関連する問題