我有一个关于 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]
并根据我的树定义定义了一个 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 类型构造函数(需要两个类型参数)的语法糖。这会导致类型推断器失败。
如果我声明我自己的 Pair 类(正如 didierd 在他的回答中所建议的那样),我成功地让 Tree 正常工作。
// 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 顺便提到了这个解决方案,但这似乎是我想要的方式。请让我知道你在想什么!