我一直在尝试消除以下F#函数中的显式参数:
let mapToSelf (s: seq<'a>): seq<'a> = s |> Seq.map id
这个带有显式参数的版本具有预期的s
推断类型seq<'a> -> seq<'a>
,我可以将其用于映射不同类型的序列:
let stringSeq = mapToSelf [ "asd"; "qwe" ]
let intSeq = mapToSelf [ 1; 2; 3 ]
到现在为止还挺好。现在,我想删除显式函数参数s
,如下所示,我(错误地?)期望它与第一个版本等效:
let mapToSelf: (seq<'a> -> seq<'a>) = Seq.map id
现在,我在这条线上收到警告:
let stringSeq = mapToSelf [ "asd"; "qwe" ]
// The construct causes code to be less generic than indicated by the type annotations
由于下一个函数现在具有签名,因此在下一行会出现错误(seq<string> -> seq<string>)
:
let intSeq = mapToSelf [ 1; 2; 3 ]
// The expression was expected to have type 'string', but here was type 'int'
我的问题是:为什么我指定的通用类型签名seq<'a> -> seq<'a>
会被通用性较弱的类型覆盖seq<string> -> seq<string>
?有没有一种方法可以在不显式指定参数的情况下声明此类函数?
您只需要用泛型类型装饰绑定:
> let mapToSelf<'T> : seq<'T> -> seq<'T> = Seq.map id;;
val mapToSelf<'T> : (seq<'T> -> seq<'T>)
> mapToSelf [| 1; 2 |];;
val it : seq<int> = seq [1; 2]
> mapToSelf [ "1"; "2" ];;
val it : seq<string> = seq ["1"; "2"]
为什么我指定的通用类型签名
seq<'a> -> seq<'a>
被一个不太通用的类型覆盖seq<string> -> seq<string>
?
由于没有用于类型泛化的函数参数,编译器会从首次使用时推断其类型。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句