から暗黙のインポート:ユーザー缶は、任意の型Tのための拡張ライブラリとして実装された文字列に型Tの値を変換するので、ここで特性は、すべての型クラスです実装する必要があります。は私がScalaでは型クラスのビット洗練された例を実装しようとしているサブクラス
trait Printable[T] {
def asString(value: T): String
}
私たちが仕事をするためにコールするつもりだ機能:いくつかのデフォルトの種類の型クラスのシリーズと
object Printer {
def print[T](value: T)(implicit p:Printable[T]): String = p.asString(value)
}
オブジェクト(だけint型&長くここに例):
object SimpleFormats extends Formats
trait Formats {
implicit val intFormat = new Printable[Int] {
override def asString(value: Int) = value.toString
}
implicit val longFormat = new Printable[Long] {
override def asString(value: Long) = value.toString
}
}
フロートとダブルのような他のタイプのライブラリを拡張したいとします。そこで彼は別のオブジェクトを作成し、最初のオブジェクトをサブクラス化します。
object ExtendedFormats extends Formats {
implicit val floatFormat = new Printable[Float] {
override def asString(value: Float) = value.toString
}
implicit val doubleFormat = new Printable[Double] {
override def asString(value: Double) = value.toString
}
}
そして、我々のライブラリを使用して最終的には、メインのアプリ:ここでのアイデアは、型クラスのデフォルトのコレクションは、ユーザーが提供するタイプの任意の数のために拡張することができるように、ベースオブジェクトに新しい暗黙のメンバーを追加することです。それはPrinter[T]
単一の特定の暗黙的に供給することはできませんので、異なる種類の操作を行う2例の機能として、があります。
- 複数の操作は
Printer
が供給されることができる種類の事前に把握していない - 複数の種類にありますユーザーによって。
だから、メインのアプリは、次のようになります。
object Example {
// compiles OK, uses only default typeclasses
def simpleExample(implicit formats: Formats) = {
import formats._
Printer.print(42) + Printer.print(24L)
}
// compilation failed, cannot find Printable[Float]
// uses user-supplied formats
def extendedExample(implicit formats: Formats) = {
import formats._
Printer.print(42f) + Printer.print(31337.0)
}
def main(args: Array[String]): Unit = {
implicit val formats = ExtendedFormats
println(simpleExample)
println(extendedExample)
}
}
私はScalaのコンパイラは、それが実際にExtendedFormats
であるという事実を無視して、Formats
から暗黙をインポートしようとしていることがわかります。
質問:
- 例で説明したように、サブクラスから暗黙にインポートする方法はありますか?
- ユーザ供給型クラスのバッチのためのよりよい解決策はありますか?
typullassesについては、[simulacrum](https://github.com/mpilquist/simulacrum)をご覧ください。 –