次のコードスニペットについて考えてみます。これは、元の問題の縮小版です。
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
タイプがあると推測されたコンパイル時エラーで失敗します。なぜ型も推測されないのですか?を使用してコンパイラーにヒントを与えるために実存型に名前を付けてみましたが、それもコンパイルされませんでした(T型が見つからなかったため、説明にも興味があります)。RandomVariable[_0]
Assignment
Any
value
_0
case (variable: RandomVariable[T forSome {type T}]) :: tail =>
さらなる動機付けのために、次のようにタイプパラメータをキャプチャするときを検討してください。
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)
これは警告/エラーなしでコンパイルされます。この余分な機能を必要としないように最初の例で変更できるものはありますか?
編集:より明確にするために、型であり、すべての値がinから来ているのに、なぜvalue
型であると推論されないのか知りたいです。また、コンパイラにこの事実を伝えるための追加の方法があるかどうかを知りたいです(上記のように関数で型をキャプチャする以外に)。_0
variable
_0
List[_0]
variable