Может кто-нибудь объяснить, почему в F# вывод типа работает по-разному (или какой-то другой аспект, который я не понимаю?) между методами класса и функциями.
Представьте себе следующее (упрощенно):
type Node<'T> = Node2 of 'T * 'T
type Digit<'T> = One of 'T | Two of 'T * 'T
type Tree<'T> =
| Empty
| Single of 'T
| Deep of prefix : Digit<'T> * deeper : Tree<Node<'T>>
with
static member Add (value : 'T) (tree : Tree<'T>) : Tree<'T> =
match tree with
| Empty -> Single value
| Single a -> Deep (One value, Empty)
| Deep (One a, deeper) -> Deep (Two (value, a), deeper)
| Deep (Two (b, a), deeper) -> Deep (One value, deeper |> Tree.Add (Node2 (b, a)))
let rec add (value : 'T) (tree : Tree<'T>) : Tree<'T> =
match tree with
| Empty -> Single value
| Single a -> Deep (One value, Empty)
| Deep (One a, deeper) -> Deep (Two (value, a), deeper)
| Deep (Two (b, a), deeper) -> Deep (One value, deeper |> add (Node2 (b, a)))
Обратите внимание, что статический метод Add
и функция add
имеют идентичную реализацию и обе вызывают себя рекурсивно.
Тем не менее, первый компилируется нормально, но последний сообщает об ошибке:
Type mismatch. Expecting a
Tree<Node<'T>> -> Tree<Node<'T>>
but given a
Tree<'T> -> Tree<'T>
The resulting type would be infinite when unifying ''T' and 'Node<'T>'