Вы просите, чтобы ваша функция возвратила тип T
, затем ваш шаблон сопоставляется с Int
и Boolean
.За исключением того, что ваша функция не имеет доказательств того, что Int
и Boolean
также имеют тип T
: при сопоставлении с шаблоном вы вводите ограничение , что Int <: T
и Boolean <: T
.Вы можете либо заменить тип возвращаемого значения T
на фиксированный тип, такой как String
, и вернуть строку, либо ввести ограничение, которое будет удовлетворять как Int
, так и Boolean
.
//this compiles
def f1[T](e: T ): String = e match {
case _:Int => "integer"
case _:Boolean => "boolean"
}
//this compiles too, but will return AnyVal
def f1[T >: AnyVal](e: T ): T = e match {
case i:Int => i
case b:Boolean => b
}
По сути, вы не можете просто динамически возвращать любой тип T
, потому что вам нужно доказать во время компиляции, что ваша функция проверяет тип.
Другая функция в вашем примере устраняет проблему, инкапсулируя ограничения типов внутри caseклассы IntExpr <: Expr[Int]
и BoolExpr <: Expr[Boolean]
(обратите внимание, что Expr[_]
будет эквивалентно T
в ограничениях, которые я упомянул выше).Во время компиляции T правильно идентифицируется во всех case
с (например, в IntExpr
вы знаете это Int
)