Scala の型コンストラクターでの型推論について質問があります。私はScala 2.9.1を実行しています...
ツリーを定義したとします:
sealed trait Tree[C[_], A]
case class Leaf[C[_], A](a: A) extends Tree[C, A]
case class Node[C[_], A](a: A, c: C[Tree[C, A]]) extends Tree[C, A]
そして、私の Tree 定義に基づいて BinaryTree を定義しました:
type Pair[A] = (A, A)
type BinaryTree[A] = Tree[Pair, A]
整数の BinaryTree を次のように定義できるようになりました。
val tree: BinaryTree[Int] = Node[Pair, Int](1, (Leaf(2), Leaf(3)))
これの問題は、インスタンス化するたびに型パラメーターを指定する必要があることNode
です。
したがって、これを行う場合:
val tree: BinaryTree[Int] = Node(1, (Leaf(2), Leaf(3)))
エラーが発生します:
error: no type parameters for method apply: (a: A, c: C[Tree[C,A]])Node[C,A] in
object Node exist so that it can be applied to arguments (Int, (Leaf[Pair,Int], Leaf[Pair,Int]))
--- because ---
argument expression's type is not compatible with formal parameter type;
found : (Leaf[Pair,Int], Leaf[Pair,Int])
required: ?C[Tree[?C,?A]]
val tree: BinaryTree[Int] = Node(1, (Leaf(2), Leaf(3)))
^
の型を明示的に指定する必要がないように、型チェッカーを強制する方法はありますNode
か?
ありがとう!
ディディアードのコメント後に改訂
私が正しく理解していれば、ステートメント
type Pair[A] = (A, A)
私の最初の質問では、この Pair 宣言は Tuple2 型コンストラクター (2 つの型パラメーターを必要とする) の単なる構文糖衣であるため、機能しません。これにより、型推論が失敗します。
独自の Pair クラスを宣言すると (ディディアードの回答で示唆されているように)、ツリーを正しく機能させることに成功します。
// Assume same Tree/Leaf/Node definition given above
case class MyPair[A](_1: A, _2: A)
type BinaryTree[A] = Tree[MyPair, A]
そしたらこれができる…
scala> val t: BinaryTree[Int] = Leaf(3)
t: BinaryTree[Int] = Leaf(3)
scala> val t2: BinaryTree[Int] = Node(1, MyPair(Leaf(2), Leaf(3)))
t2: BinaryTree[Int] = Node(1,MyPair(Leaf(2),Leaf(3)))
ディディアードがこの解決策について言及したことは知っていますが、これは私が望むように動作するようです。あなたの考えを教えてください!