【发布时间】:2012-03-20 01:55:06
【问题描述】:
我无法理解 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'
我不清楚为什么 lowerstring3 和 lowerstring4 的类型检查不同。静态约束似乎很可能,但如果是这种情况,那么lowerstring4 不应该无法概括吗?为什么函数参数的显式存在会在这里有所作为?
【问题讨论】:
-
第一个是value,不能泛型;后者是一个函数,它可以。介绍
inline并享受一些真正的乐趣。
标签: types f# type-inference