Вывод типа Scala на экзистенциальный тип
Рассмотрим следующий фрагмент кода, который является уменьшенной версией моей первоначальной проблемы:
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
}
Это терпит неудачу с ошибкой времени компиляции, котораяvariable
был сделан вывод, чтобы иметь типRandomVariable[_0]
когдаAssignment
требуемый типAny
. Почему value
также не подразумевается, чтобы иметь тип _0
? Я попытался дать экзистенциальному типу имя, чтобы дать подсказку компилятору с помощьюcase (variable: RandomVariable[T forSome {type T}]) :: tail =>
но это также не скомпилировало бы (говоря, что оно не может найти тип T, который я также заинтересован в объяснении).
Для дальнейшей мотивации рассмотрим, когда мы фиксируем параметр типа следующим образом:
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)
Это компилируется без предупреждений / ошибок. Что-то, что я могу изменить в первом примере, чтобы не требовать этой дополнительной функции?
РЕДАКТИРОВАТЬ: Чтобы быть более явным, я хочу знать, почемуvalue
не подразумевается, чтобы быть типа_0
даже не смотря наvariable
имеет тип_0
и каждое значение исходит отList[_0]
вvariable
, Также я хотел бы знать, есть ли какие-либо дополнительные способы сообщить компилятору об этом факте (кроме захвата типа в функции, как я дал выше).