在哪里添加类型注释到curried函数?

时间:2012-07-05 07:47:23

标签: f#

在F#interactive中,我可以找到sprintf的类型。

>sprintf;;
val it : (Printf.StringFormat<'a> -> 'a) = <fun:clo@163>

如果curried函数不是通用的,我可以找到第一个参数的sprintf类型。

> sprintf "%g";;
val it : (float -> string) = <fun:it@134-16>

但如果它是通用的,那么我会得到值限制错误。

> sprintf "%A";;
error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it : ('_a -> string)    
Either make the arguments to 'it' explicit or, if you do not intend for it to be generic, add a type annotation.

我可以添加一个类型注释来摆脱像这样的值限制,专门用于类型的函数,例如。日期时间。

>let f : (DateTime -> string) = sprintf "%A";;
val f : (DateTime -> string)

如何在没有绑定的情况下添加类型注释?我试过以下......

>sprintf "%A" : (DateTime -> string);;
error FS0010: Unexpected symbol ':' in interaction. Expected incomplete structured construct at or before this point, ';', ';;' or other token.

这是一个类似的例子,但更难......

>sprintf "%a";;
error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it : ((unit -> '_a -> string) -> '_a -> string)    
Either make the arguments to 'it' explicit or, if you do not intend for it to be generic, add a type annotation.

2 个答案:

答案 0 :(得分:3)

您只需将表达式括在括号中:

open System;;
(sprintf "%A" : DateTime -> string);;

val it : (DateTime -> string) = <fun:it@2>

这样你可以指定没有绑定的类型注释。

答案 1 :(得分:1)

实际发生的是fsi将您输入的最后一个内容绑定到名为it的变量。它有效地做到了

let it = sprintf "%a";;

类型注释需要放在您无法访问的=的左侧。问题是你需要一个具体的类型来赋予任何变量(在这种情况下是it)。解决方法可能是

(fun t:DateTime -> sprintf "%a" t)