Skalatyp-Inferenz auf einen existenziellen Typ
Betrachten Sie den folgenden Codeausschnitt, der eine reduzierte Version meines ursprünglichen Problems ist:
case class RandomVariable[A](values: List[A])
case class Assignment[A](variable: RandomVariable[A], value: A)
def enumerateAll(vars: List[RandomVariable[_]], evidence: List[Assignment[_]]): Double =
vars match {
case variable :: tail =>
val enumerated = for {value <- variable.values
extendedEvidence = evidence :+ Assignment(variable, value)
} yield enumerateAll(tail, extendedEvidence)
enumerated.sum
case Nil => 1.0
}
Dies schlägt mit dem Kompilierungsfehler fehlvariable
wurde gefolgert, um Art zu habenRandomVariable[_0]
wannAssignment
erforderlicher TypAny
. Warum ist value
Es wird auch nicht davon ausgegangen, Typ zu haben _0
? Ich habe versucht, dem existenziellen Typ einen Namen zu geben, um dem Compiler mithilfe von einen Hinweis zu gebencase (variable: RandomVariable[T forSome {type T}]) :: tail =>
aber das würde auch nicht kompilieren (sagen, es könnte nicht den Typ T finden, für den ich auch eine Erklärung haben möchte).
Überlegen Sie zur weiteren Motivation, wann wir den Typparameter wie folgt erfassen:
case variable :: tail =>
def sum[A](variable: RandomVariable[A]): Double = {
val enumerated = for {value <- variable.values
extendedEvidence = evidence :+ Assignment(variable, value)
} yield enumerateAll(tail, extendedEvidence)
enumerated.sum
}
sum(variable)
Dies wird ohne Warnungen / Fehler kompiliert. Gibt es etwas, das ich im ersten Beispiel ändern kann, um diese zusätzliche Funktion nicht zu benötigen?
BEARBEITEN: Um genauer zu sein, ich möchte wissen warumvalue
Es wird nicht davon ausgegangen, dass es sich um einen Typ handelt_0
obwohlvariable
ist vom Typ_0
und jeder Wert kommt von aList[_0]
imvariable
. Ich würde auch gerne wissen, ob es zusätzliche Möglichkeiten gibt, den Compiler über diese Tatsache zu informieren (abgesehen von der Erfassung des Typs in einer Funktion, wie ich sie oben angegeben habe).