2014-03-15 4 views
3

У меня есть следующий довольно простой 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

Я не думаю, что 'string.Format' всегда действует в F #. Это должно быть 'System.String.Format' или' String.Format' с 'открытой системой' раньше. Кроме того, следует упомянуть, что вы используете подробный синтаксис. –

+0

Спасибо, что сделал; Мне нужно было использовать класс вместо типа. Можете ли вы добавить это как ответ, чтобы я мог принять его? (О, и я действительно не использую подробный синтаксис, 'in' просто проскользнул, пока я пытался заставить его работать.) – TeaDrivenDev

ответ

2

Проблема заключалась в том, что string.Format недействителен в коде F #.

Вам нужно либо использовать

System.String.Format 

или

open System 
..... 
String.Format 

(разница сверху по сравнению с нижней случае s в string

3

ответ Джона Палмера правильно, но я часто имею интересно, почему string.Format is не действителен в коде F #, и до этого вопроса я h объявление не потрудилось исследовать его.

Рассматривая 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 и т. Д.).

Смежные вопросы