Domanda

I have the following rather simple F# function:

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 -> ""

The return type is correctly inferred as string, however I get an error marker at string.Format in the true branch, saying the type <'a> -> string is not compatible with type ValueSuffix. I find this especially surprising as all other types are inferred correctly, and in particular there is no other occurrence of <'a> in the function.

What am I doing and/or understanding wrong?

È stato utile?

Soluzione 2

The issue was that string.Format is not valid in F# code.

You need to either use

System.String.Format

or

open System
.....
String.Format

(The difference is upper versus lower case s in string

Altri suggerimenti

John Palmer's answer is correct, but I've often wondered why string.Format is not valid in F# code, and until this question I had not bothered to investigate it.

Looking at the relevant source, we see that string is just a type alias for System.String. So it seems like we should be able to use it just like System.String. For example, suppose we define the following type alias:

type foo = System.String

This will allow us to do things like foo.Format without issue.

The problem is that not only is string defined as a type alias, it is also defined as conversion function. This effectively shadows the type alias except in contexts where only a type name could be expected (e.g. type annotations and casts).

We can demonstrate this by defining our own conversion function to shadow our foo type alias:

let foo value = 
    match box value with
    | null -> ""
    | _ -> value.ToString()

Now the aformentioned foo.Format call will not compile.

The same goes with all the other basic types (int, float, etc.).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top