私はScalaの型コンストラクタの型推論に関する質問があります。型コンストラクタの型推論
type Pair[A] = (A, A)
type BinaryTree[A] = Tree[Pair, A]
私は今BinaryTreeを定義することができます:私のツリーの定義に基づいてBinaryTreeを
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]
と定義される:私はツリーを定義したと仮定し
Scalaの2.9.1を...実行していますよのような整数の:
val tree: BinaryTree[Int] = Node[Pair, Int](1, (Leaf(2), Leaf(3)))
私はタイプパラメータを入力する必要がありますstantiate Node
。これを行う場合
だから:
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)))
^
私は明示的に供給する必要がないように、私は型チェッカを強制することができますどのような方法があります:
val tree: BinaryTree[Int] = Node(1, (Leaf(2), Leaf(3)))
私はエラーを取得しますNode
の種類?
ありがとうございます!私が正しく理解していた場合didierdのコメント
後改訂
このペア宣言は単なる糖衣構文であることから、文の私の元の質問で
type Pair[A] = (A, A)
は動作しません。 Tuple2型コンストラクタ(これには2つの型パラメータが必要です)。これにより、型推論が失敗します。
私が自分のペアクラスを宣言した場合(didierdが答えて示すように)、私は正しくツリーが動作するように成功しています。
// 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)))
私はdidierdパッシングでこのソリューションを言及知っているが、これは私が望むように振る舞うように見えます。あなたの考えを教えてください!
改訂コードについて:@ Davidのソリューションに近いです。型が完全に推測されていない場合は、式をBinaryTree [Int]として明示的に入力する必要があります。これはかなり合理的だと思います。共変の解決策はそれを避けますが、それには価格が付いています。共分散は大部分が良いことですが、クラスができることを制限します。特に、共変量であるタイプCでのみ動作します。 –