为什么我的功能不直观概括?

时间:2012-03-20 01:55:07

标签: types f# type-inference

我无法理解F#类型推理器的行为。运算符string在编译时依赖于静态类型调度,而不是运行时,这就是为什么let lowerstring = string >> (fun s -> s.ToLowerInvariant())之类的东西不是通用的 - 编译器需要知道参数的类型。但是,我看到了一些奇怪的行为。

具有以下定义:

let inline lower (s: string) = s.ToLowerInvariant()

// 'T -> string, constrained to the type of its first use
let lowerstring1 = string >> lower

// Same as above
let lowerstring2 value = value |> string |> lower

// Same as above
let lowerstring3 = box >> string >> lower

// 'a -> string, fully generalized
let lowerstring4 value = value |> box |> string |> lower

我观察到这种行为:

// val token: JToken
// val num: int

let tokstr1 = lowerstring1 token // lowerstring1 now has type JToken -> string
let numstr1 = lowerstring1 num   // Error, doesn't compile

(* As above with lowerstring2 and lowerstring3 *)

let tokstr4 = lowerstring4 token // lowerstring4 now has type 'a -> string
let numstr4 = lowerstring4 num   // no error, works as 'expected'

我不清楚为什么lowerstring3lowerstring4的格式不同。静态约束似乎很可能,但如果是这种情况,那么lowerstring4是否应该不能概括?为什么函数参数的显式存在会产生差异呢?

1 个答案:

答案 0 :(得分:1)

F#必须将代码转换为IL,并且由于.NET中没有通用的“值”,因此只有当它们是真正的合成函数(生成为可以是通用的.NET方法)时才会生成函数。 / p>

(一个例外是[<GeneralizableValueAttribute>],请参阅例如here。)