我有以下相当简单的F#功能:
let FormatValue (formatProvider : IFormatProvider) valueSuffix value =
match value > Convert.ToDecimal(valueSuffix.MinimumValueRequired) with
| true -> let normalizedValue = Convert.ToDecimal(value) / Convert.ToDecimal((Math.Pow(10., Convert.ToDouble(valueSuffix.PowerOfTen)))) in
string.Format("{0}{1}", normalizedValue.ToString(valueSuffix.Format, formatProvider), valueSuffix.Text)
| false -> ""
返回类型被正确推断为string
,但我在string.Format
分支的true
处收到错误标记,表示类型<'a> -> string
与类型不兼容ValueSuffix
。我发现这一点特别令人惊讶,因为所有其他类型都是正确推断的,特别是函数中没有出现<'a>
。
我在做什么和/或理解错误?
答案 0 :(得分:3)
John Palmer的回答是正确的,但我经常想知道为什么string.Format
不在F#代码中有效,直到这个问题我没有费心去研究它。
查看relevant source,我们发现string
只是System.String
的类型别名。因此,似乎我们应该能够像System.String
一样使用它。例如,假设我们定义以下类型别名:
type foo = System.String
这样我们就可以毫无问题地执行foo.Format
之类的操作。
问题在于string
不仅被定义为类型别名,它还是also defined作为转换函数。这有效地隐藏了类型别名,除了在只能预期类型名称的上下文中(例如类型注释和强制转换)。
我们可以通过定义我们自己的转换函数来证明这一点,以遮蔽我们的foo
类型别名:
let foo value =
match box value with
| null -> ""
| _ -> value.ToString()
现在,前面提到的foo.Format
调用将无法编译。
所有其他基本类型(int
,float
等)都是如此。
答案 1 :(得分:2)
问题是string.Format
在F#代码中无效。
您需要使用
System.String.Format
或
open System
.....
String.Format
(s
string