Ho una domanda riguardante l'inferenza di tipo sui costruttori di tipi di Scala. Io corro Scala 2.9.1 ...Tipo-Inferenza Scala Tipo Costruttore
Supponiamo che io definito Albero:
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]
e definito un BinaryTree basata sulla mia definizione Albero:
type Pair[A] = (A, A)
type BinaryTree[A] = Tree[Pair, A]
Ora posso definire un BinaryTree di interi quanto tali:
val tree: BinaryTree[Int] = Node[Pair, Int](1, (Leaf(2), Leaf(3)))
Il problema è che ho per fornire i parametri di tipo ogni volta che in stantiate Node
.
Quindi, se fare questo:
val tree: BinaryTree[Int] = Node(1, (Leaf(2), Leaf(3)))
ottengo l'errore:
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)))
^
C'è un modo per costringere il tipo ortografico in modo che io non devo fornire esplicitamente il tipi di Node
?
Grazie!
revisione previa Commenti di didierd
Se ho la comprensione correttamente, la dichiarazione
type Pair[A] = (A, A)
nella mia domanda iniziale non funziona in quanto questa dichiarazione Pair è solo zucchero sintattico per un costruttore di tipi Tuple2 (che richiede due parametri di tipo). Ciò causa il fallimento del tipo-inferneratore.
Se io dichiaro la mia classe di coppia (come didierd suggerisce nella sua risposta), io sono riuscita a ottenere l'Albero per funzionare correttamente.
// Assume same Tree/Leaf/Node definition given above
case class MyPair[A](_1: A, _2: A)
type BinaryTree[A] = Tree[MyPair, A]
Allora posso fare questo ...
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)))
So didierd menzionato questa soluzione di passaggio, ma questo sembra a comportarsi nel modo desiderato. Per favore fatemi sapere cosa ne pensate!
Per quanto riguarda il codice rivisto: è più simile alla soluzione di @ David. I tipi non sono completamente dedotti, è necessario digitare esplicitamente l'espressione come BinaryTree [Int].Penso che questo sia abbastanza ragionevole. La soluzione covariante lo evita, ma ha un prezzo: mentre la covarianza è principalmente una buona cosa, limita ciò che la classe può fare. In particolare, funziona solo con i tipi C che sono covarianti. –