F#递归类型:方法与函数类型推断的差异
有人能解释一下为什么在F#类型推断中,类方法和函数之间的工作方式不同(或者我不理解的其他方面) 想象一下如下(简化):F#递归类型:方法与函数类型推断的差异,f#,type-inference,recursive-datastructures,recursive-type,F#,Type Inference,Recursive Datastructures,Recursive Type,有人能解释一下为什么在F#类型推断中,类方法和函数之间的工作方式不同(或者我不理解的其他方面) 想象一下如下(简化): 在自由浮动函数add中,泛型类型参数属于函数本身(add) 为什么这很重要?因为当您引用函数本身时,除非另有指定,否则编译器假定类型参数不变。它不会猜出另一个,因为这可能会隐藏大量类型不匹配错误 但是,对于函数所属的类型,它没有做出相同的假设 如果检查参数,则对add的调用假定为对add.add的调用。这是一个完全不同的函数调用 如果显式注释类型: static member
在自由浮动函数
add
中,泛型类型参数属于函数本身(add
)
为什么这很重要?因为当您引用函数本身时,除非另有指定,否则编译器假定类型参数不变。它不会猜出另一个,因为这可能会隐藏大量类型不匹配错误
但是,对于函数所属的类型,它没有做出相同的假设
如果检查参数,则对add
的调用假定为对add.add
的调用。这是一个完全不同的函数调用
如果显式注释类型:
static member Add (value : 'T) (tree : Tree<'T>) : Tree<'T> =
// ...
| Deep (Two (b, a), deeper) -> Deep (One value, deeper |> Tree<'T>.Add (Node2 (b, a)))
静态成员添加(值:'T)(树:树=
// ...
|Deep(两个(b,a),更深)->Deep(一个值,更深|>Tree=
// ...
|Deep(两个(b,a),Deep)->Deep(一个值,Deep |>this.Add(Node2(b,a)))
反之亦然,您可以通过注释类型参数来编译自由函数,这样编译器就不会假设“它是相同的符号,所以必须引用相同的值”:
让rec添加=
// ...
|Deep(两(b,a),Deep)->Deep(一个值,Deep |>add(Node2(b,a)))
实际上,即使只是在函数绑定中添加类型参数'let rec addOh,很好。似乎编译器只会在名称完全相同的情况下进行相同的实例假设。我更正了我的答案。
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>'
static member Add (value : 'T) (tree : Tree<'T>) : Tree<'T> =
// ...
| Deep (Two (b, a), deeper) -> Deep (One value, deeper |> Tree<'T>.Add (Node2 (b, a)))
member this.Add (value : 'T) (tree : Tree<'T>) : Tree<'T> =
// ...
| Deep (Two (b, a), deeper) -> Deep (One value, deeper |> this.Add (Node2 (b, a)))
let rec add<'T> (value : 'T) (tree : Tree<'T>) : Tree<'T> =
// ...
| Deep (Two (b, a), deeper) -> Deep (One value, deeper |> add (Node2 (b, a)))