函数返回类型问题不明确

时间:2014-03-15 00:20:03

标签: f# type-inference

我有以下相当简单的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>

我在做什么和/或理解错误?

2 个答案:

答案 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调用将无法编译。

所有其他基本类型(intfloat等)都是如此。

答案 1 :(得分:2)

问题是string.Format在F#代码中无效。

您需要使用

System.String.Format

open System
.....
String.Format

s

中的差异是大写与小写string