У меня есть вопрос относительно вывода типов в конструкторах типов 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 (как предлагает Дидье в своем ответе), мне удастся заставить дерево работать правильно.
// 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 мимоходом упомянул это решение, но, похоже, оно ведет себя так, как я хочу. Пожалуйста, дайте мне знать, что вы думаете!