繁体   English   中英

为什么在这种情况下F#类型推断不起作用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM