вывод типа в F # - PullRequest
       43

вывод типа в F #

3 голосов
/ 03 декабря 2011

В F # почему моя функция добавления не добавляет два числа с плавающей запятой

let add a b = a+b

(add 3 4) //returns 7
(add 3.5 5.5) //error

Также, пожалуйста, объясните, как вывод типов работает в F #.

Спасибо.

Ответы [ 4 ]

7 голосов
/ 04 декабря 2011

Вы должны сделать это встроенным.

let inline add a b = a+b

Проблема в том, что + является встроенным оператором, поэтому, если ваша функция add не является встроенной, она получит перегрузку по умолчанию для int.

Посмотрите на этот ответ Использование `inline` в F #

Когда функция объявлена ​​встроенной, вывод типа выведет ограничения статического типа.

val inline add :
   ^a ->  ^b ->  ^c
    when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^c)

Так что теперь a и b могут быть любыми типами, которые реализуют статический член (+) с этой подписью.

2 голосов
/ 04 декабря 2011

Если вы хотите, чтобы ваша функция работала только с плавающей точкой, используйте аннотацию типа.

let add (a:float) b = a + b //float -> float -> float
0 голосов
/ 02 ноября 2013

Мои два цента здесь.

На самом деле, если вы измените порядок выполнения на,

let add a b = a+b

(add 3.5 5.5) //returns 9.0
(add 3 4) //error

Вы увидите, что F # действительно добавляет к двум числам с плавающей запятой.(Это отвечает на ваш вопрос В F #, почему моя функция добавления не добавляет два числа с плавающей точкой)

И обратите внимание, что в этом фрагменте F # выводит функцию добавления типа как float -> float -> float.

Почему F # выводит тип функции по-разному в двух случаях, даже если вы определяете функцию точно таким же образом?

Я думаю, что когда вы определяете функцию, F # дает тип int функции.Но внутри F # остается гибким в отношении «истинного» типа функции.В первый раз, когда вы вызываете функцию, компилятор видит, как вы ее используете, и, таким образом, компилятор понимает ваше «намерение» типа функции.И компилятор корректирует тип соответствующим образом.

Как только компилятор «думает», он получает «истинный тип» функции, он становится тем, чем он является.И поскольку F # статически типизирован, вы не можете сделать второй вызов функции с аргументом другого типа.

При этом я рекомендую вам попробовать этот фрагмент.

let add a b = a + b

add "str" "ing"

Это должно сработать.

let add a b = a + b

add 5. 6.
add "str" "ing" // error, check the type

Поправь меня, если я ошибаюсь.Надеюсь, это поможет.

0 голосов
/ 04 декабря 2011

В F # система определения типов просто ставит тип int, когда вы имеете дело с числами, из-за технических ограничений. В Haskell add :: Num a => a -> a -> a работает из-за классов типов, которые отличаются от классов .NET. Классы не соответствуют F #.

См. http://en.wikibooks.org/wiki/F_Sharp_Programming/Basic_Concepts#Type_Inference и http://en.wikibooks.org/wiki/F_Sharp_Programming/Values_and_Functions

...