2015-09-17 2 views
2

У меня есть простая функция F # cost, получающая единственный параметр amount, который используется для некоторых расчетов. Это float, поэтому мне нужно передать что-то вроде cost 33.0, которое в математике совпадает с cost 33. Компилятор жалуется на это, и я понимаю, почему, но я хотел бы, чтобы это можно было назвать так, я попытался создать еще одну функцию с именем той же и используемой аннотации типа для обоих из них, а также получить предупреждения о компиляторе. Есть ли способ сделать это, как это делает C#?Перегрузка функции F # с тем же номером параметра

+0

Что будет (в идеале) возвращаемым типом вашей функции стоимости? Всегда поплавок, такой же, как вход или другой тип? Это небольшая деталь, но она может определить, куда идти. – Gustavo

ответ

7

Существуют два механизма в F # для достижения этой цели, и оба не полагаться на неявные слепков "как C#":

(A) Способ перегрузки

type Sample = 
    static member cost (amount: float) = 
     amount |> calculations 
    static member cost (amount: int) = 
     (amount |> float) |> calculations 

Sample.cost 10 // compiles OK 
Sample.cost 10. // compiles OK 

(B) Using inlining

let inline cost amount = 
    amount + amount 

cost 10 // compiles OK 
cost 10. // compiles OK 
+0

inlining не будет работать, если функция стоимости использует некоторый плавающий литерал, например 'let inline cost amount = amount * 2. // val inline cost: float -> float' – Sehnsucht

+0

@Sehnsucht, существуют специальные примитивы для использования в общих функциях. Проверьте 'LanguagePrimitives.GenericOne'. – bytebuster

+0

@bytebuster уверен, что я знаю, моя точка зрения заключалась в том, что просто добавить 'inline' перед именем не всегда может быть достаточно. есть «GenericOne» и «GenericZero», мы можем даже делать некоторые вещи, используя «AdditionDynamic» и т. д., но это требует больших изменений. – Sehnsucht

0

если вы хотите использовать int на сайте вызова, но иметь поплавок внутри тела функции; почему бы просто не бросить его?

let cost amount = 
    // cast amount from to float (reusing the name amount to shadow the first one) 
    let amount = float amount 
    // rest of your function 
+0

Я хочу иметь возможность использовать оба варианта, иногда это может быть что-то вроде '38.6', это просто для облегчения, когда это не так (например, когда это' 39.0' сказать) – Luiso

+0

@Luiso в системе типа F #; '33' и' 33.' (обратите внимание на точку) не то же самое и не являются взаимозаменяемыми. Если вы хотите последнего, вы не можете написать прежнего в одиночку и ожидать, что код угадает, что вы на самом деле имеете в виду. – Sehnsucht

2

F # не разрешает перегрузку функций с привязкой, но вы можете перегружать методы на classe как на C#.

Иногда вы можете использовать change the model to work on a Discriminated Union вместо набора перегруженных примитивов, но я не думаю, что было бы особенно разумно делать это, чтобы иметь возможность различать поплавки и целые числа.

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