Types 为什么不是';我的函数不是直观地推广的吗?
我很难理解F#型推理机的行为。运算符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
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
并享受真正的乐趣。