Ответ 1
Тип вывода и подтипирование не очень хорошо сочетаются, так как ссылки Carsten обсуждают в некоторой степени. Похоже, вы недовольны подходом F # и предпочтете, чтобы
if b then
e1
else
e2
были неявно обработаны более как
if b then (e1 :> 'a) else (e2 :> 'a)
когда компилятор дополнительно выводит 'a
как наименьшую верхнюю границу иерархии типов на основе типов, которые в противном случае были бы определены для e1
и e2
.
Возможно, это будет технически возможно, и я не могу окончательно говорить о том, почему F # не работает таким образом, но здесь есть предположение: если бы инструкции if
вели себя таким образом, то никогда не было бы ошибкой имеют разные типы в ветвях if
и else
, поскольку они всегда могут быть унифицированы путем неявного повышения их до obj
. Однако на практике это почти всегда ошибка программиста - вы почти всегда хотите, чтобы типы были одинаковыми (например, если я возвращаю символ из одной ветки и строку из другой, я, вероятно, должен был возвращать строки из обоих, а не obj
). Неявным повышением уровня, вы просто затруднили бы обнаружение этих ошибок.
Кроме того, в F # относительно редко встречается сложная иерархия наследования, за исключением, возможно, при взаимодействии с другим кодом .NET. В результате это на практике очень незначительное ограничение. Если вы ищете синтаксически более короткое решение, чем upcast
, вы можете попробовать :> _
, который будет работать до тех пор, пока есть что-то, чтобы ограничить тип (либо аннотацию на общий результат, либо конкретный отбор на одном ветвей).