Types 为什么不是';我的函数不是直观地推广的吗?

Types 为什么不是';我的函数不是直观地推广的吗?,types,f#,type-inference,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

我很难理解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
不应该无法概括吗?为什么函数参数的显式存在会造成差异?

F#必须将其编码为IL,而且由于.NET中没有通用的“值”,因此函数只有在它们是真正的同步函数(生成到一个可以通用的.NET方法中)时才会生成

(一个例外是
[]
,请参见示例)

F#必须将gen编码到IL,并且由于.NET中没有通用的“值”,因此只有当函数是真正的同步函数(生成到可以是通用的.NET方法中)时,才会生成函数

(一个例外是
[]
,请参见示例)

第一个是一个值,不能是通用的;后者是一个函数,可以。介绍
inline
并享受一些真正的乐趣。首先是一个值,它不能是通用的;后者是一个函数,可以。介绍
inline
并享受真正的乐趣。