3

F# インタラクティブでは、sprintf の型を見つけることができます。

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

カリー化された関数がジェネリックでない場合、最初のパラメーターでカリー化された 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.
4

2 に答える 2

3

式を括弧で囲むだけです。

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

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

そうすれば、バインディングなしで型注釈を指定できます。

于 2012-07-05T08:11:20.670 に答える
1

実際に起こっていることは、 fsi が最後に入力したものを という変数にバインドすることですit。それは効果的に行います

let it = sprintf "%a";;

型注釈は、アクセスできない の左側に配置する必要=があります。問題は、任意の変数 (この場合はit) に与える具体的な型が必要なことです。回避策は次のとおりです。

(fun t:DateTime -> sprintf "%a" t)
于 2012-07-05T08:05:45.130 に答える