[英]Why is F# type inference not working in this case
在以下情况下
let a = [1]
let f x = x
let b = a |> List.map f
a是一个int列表。 我们调用List.map,因此可以肯定f必须是int->? 功能。 为什么f仍然键入'a->'a而不是int-> int? 如果这是类型推理(不)在F#中的工作方式,那么我看不到有什么好处。
是否有一种解决方法,而没有明确指定f中x的类型? 假设x具有类型(A * B * C列表(D选项,E列表))
另外一件有趣的事情:
open System.Collections.Generic
let d = new Dictionary()
d.[1] ="a"
除非删除了“ new”关键字,否则这将不起作用。
类型推断在这里可以正常工作。 f
被推断为具有类型'a -> 'a
,这意味着它将采用通用类型'a
的值并返回相同通用类型'a
。
在这种情况下,键入当您使用它推理踢。 因为a
具有类型int list
,并且因为List.map
具有签名('T -> 'U) -> 'T list -> 'U list
,所以它可以从表达式中推断类型。
let b = a |> List.map f
在这种情况下, 'T list
参数为a
,因此其类型为int list
。 这意味着它现在知道'T
is int
。
传递给List.map
的函数的通用格式为'T -> 'U
,但是在这种情况下,我们传递f
,其格式为'a -> 'a
,等效于'T -> 'T
。 因此,编译器理解在这种情况下, 'T
和'U
是相同的类型。
这意味着它可以推断返回类型'U list
也必须是int list
。
函数f
的类型为'a -> 'a
因为它适用于每种类型,而不仅限于int
:
> f "foo";;
val it = "foo" : string
> f 0.8;;
val it = 0.8 : float
这是一个优势:泛型类型'a -> 'a
使您可以在安全的情况下自由使用f
,而不是仅使用int -> int
类型。
为此处已列出的最佳答案添加一些内容。
在某些情况下,您将不希望使用泛型推断类型。 f的通用版本将比特定于类型的版本慢。 但是F#有一个关键字可以为您解决这个问题:
let inline f x = x
它告诉编译器使用应用于x的任何操作的特定于类型的版本。 推断的类型将保持通用。 您只需要在时间紧迫的代码部分中使用它。
如其他地方所述,泛型推断是一件有用的事情,您可能会逐渐喜欢上它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.