そのメソッドに渡される引数の型とそれを囲むトレイトの型パラメーターに依存する returntype を持つメソッドを定義したいと考えています。私が言いたいことを言葉で説明するのは非常に難しいので、以下にいくつかの抜粋を示します。
私はいくつかのビルディングブロックを持っています
// This is the target of a binding
trait BindableValue[T] {
def set(value: T): Unit
// this is the method I am strugling with
def bindTo[S](o: S) = ???
}
// This will dispatch events of type T
trait Observable[T]
// This represents a value of type T that will
// dispatch events if the value changes
trait ObservableValue[T] extends Observable[T] {
def value: T
}
// An Observable can be converted to an optional ObservableValue
object ObservableValue {
implicit def wrap[T](o:Observable[T]):ObservableValue[Option[T]] =
new ObservableValue[Option[T]] {
val value = None
}
}
バインディングにはソースとターゲットがあり、次の 2 種類があります。
- 完全: ソースとターゲットの両方のタイプ パラメータが同じです
- 不完全: ソースとターゲットの型パラメーターが異なります
...
trait Binding[S, T] {
def source: ObservableValue[S]
def target: BindableValue[T]
}
class CompleteBinding[T](
val source: ObservableValue[T],
val target: BindableValue[T]) extends Binding[T, T]
class IncompleteBinding[S, T](
val source: ObservableValue[S],
val target: BindableValue[T]) extends Binding[S, T]
次のインスタンスを構築できます。
val bindable1 = new BindableValue[Int] { def set(value:Int) = {} }
val property1 = new ObservableValue[Int] { def value = 0 }
val property2 = new ObservableValue[String] { def value = "" }
val bindable2 = new BindableValue[Option[Int]] { def set(value:Option[Int]) = {} }
val event1 = new Observable[Int] {}
val event2 = new Observable[String] {}
これらのインスタンスを次のように使用したいと思います。
// 'a' should be of type CompleteBinding
val a = bindable1 bindTo property1
// 'b' should be of type IncompleteBinding
val b = bindable1 bindTo property2
// 'c' should be of type CompleteBinding
val c = bindable2 bindTo event1
// 'd' should be of type IncompleteBinding
val d = bindable2 bindTo event2
bindTo
上記の4行をコンパイルし、すべての値に対して正しい具象型を持つようにメソッドを定義する方法がわかりません。Scala 型システムに関する知識が欠けているだけです。
私は解決策を見つけたいと思っていますが、将来そのような解決策に到達する方法も理解したいと思っています。上記の問題の解決策がある場合は、自分自身を教育するために使用できる情報源をいくつか教えていただけますか?