Numeric
オブジェクトでの型クラスの使用には、囲んでいるスコープのどこかにバインドする必要がInterval
ある型パラメーターがあります。は一意の定数値であるため、そのバインディングを提供できません。T
Interval
この特定の問題に対する1つの解決策はunion
、intersect
操作の定義を通常のインスタンスメソッドとしてInterval
クラスに移動することです。この場合、それらはクラスの残りの部分とのバインディングT
と関連するインスタンスを共有します。Numeric
case class Interval[T : Numeric](from: T, to: T) {
import Numeric.Implicits._
import Ordering.Implicits._
def mid: Double = (from.toDouble + to.toDouble) / 2.0
def union(interval2: Interval[T]) =
Interval(this.from min interval2.from, this.to max interval2.to)
def intersect(interval2: Interval[T]) =
Interval(this.from max interval2.from, this.to min interval2.to)
}
ただし、これらの操作の定義をクラスから分離しInterval
たい場合は、APIを追跡する必要がある暗黙のボイラープレートの量を減らすための1つのアプローチは、Numeric[の観点から独自の高レベルの型クラスを定義することです。 T]。例えば、
// Type class supplying union and intersection operations for values
// of type Interval[T]
class IntervalOps[T : Numeric] {
import Ordering.Implicits._
def union(interval1: Interval[T], interval2: Interval[T]) =
Interval[T](interval1.from min interval2.from, interval1.to max interval2.to)
def intersect(interval1: Interval[T], interval2: Interval[T]) =
Interval[T](interval1.from max interval2.from, interval1.to min interval2.to)
}
implicit def mkIntervalOps[T : Numeric] = new IntervalOps[T]
使用中は次のようになります。
def use[T](i1 : Interval[T], i2 : Interval[T])(implicit ops : IntervalOps[T]) = {
import ops._
val i3 = union(i1, i2)
val i4 = intersect(i1, i2)
(i3, i4)
}
3番目のオプションは、これら2つを組み合わせ、暗黙的な定義を使用して、元のクラスを追加のメソッドで強化します。
class IntervalOps[T : Numeric](interval1 : Interval[T]) {
import Ordering.Implicits._
def union(interval2: Interval[T]) =
Interval[T](interval1.from min interval2.from, interval1.to max interval2.to)
def intersect(interval2: Interval[T]) =
Interval[T](interval1.from max interval2.from, interval1.to min interval2.to)
}
implicit def enrichInterval[T : Numeric](interval1 : Interval[T]) =
new IntervalOps[T](interval1)
type Ops[T] = Interval[T] => IntervalOps[T]
その後、使用中、
def use[T](i1 : Interval[T], i2 : Interval[T])(implicit ops : Ops[T]) = {
val i3 = i1 union i2
val i4 = i1 intersect i2
(i3, i4)
}