Есть ли уловки для неявных преобразований в F #? - PullRequest
4 голосов
/ 02 ноября 2010

Рассмотрим этот код F # для суммирования чисел ниже i, кратных 3 и 5:

let isMultipleOfThreeOrFive n = 
    (n % 3 = 0) || (n % 5 = 0)

let sequenceOfMultiples i =
    seq {1 .. i - 1} |> Seq.filter isMultipleOfThreeOrFive

Поскольку i является int, вы переполнитесь, если iбольшой.Эта версия с BigInteger позаботится об этом:

let isMultipleOfThreeOrFive n = 
    (n % 3I = 0I) || (n % 5I = 0I)

let sequenceOfMultiples (i : System.Numerics.BigInteger) =
    seq {1I .. i - 1I} |> Seq.filter isMultipleOfThreeOrFive

Чтобы преобразовать версию int в версию BigInteger, мне пришлось добавить множество I s после чисел.Это потому, что F # не делает неявных преобразований.

Есть ли простой способ обойти это, или было лучше всего добавить I s в 6 местах?

Ответы [ 2 ]

6 голосов
/ 02 ноября 2010

Это не совсем отвечает на ваш вопрос, но обратите внимание, что также можно сделать sequenceOfMultiples универсальным, определив свой собственный числовой литерал:

module NumericLiteralG =
  let inline FromZero() = LanguagePrimitives.GenericZero
  let inline FromOne() = LanguagePrimitives.GenericOne
  let inline FromInt32 (i:int) =
    let zero : ^a = FromZero()
    let one : ^a = FromOne()
    let rec compute : int -> ^a = function
    | 0 -> zero
    | n -> 
        let half = compute (n/2)
        let whole = half + half
        if (n%2 = 0) then whole
        else whole + one
    compute i

let inline isMultipleOfThreeOrFive n = 
    (n % 3G = 0G) || (n % 5G = 0G)

let inline sequenceOfMultiples i =
    seq {1G .. i - 1G} |> Seq.filter isMultipleOfThreeOrFive

let bigintSeq = sequenceOfMultiples 100I
let intSeq = sequenceOfMultiples 100

// doesn't compile
let stringSeq = sequenceOfMultiples "100"
5 голосов
/ 02 ноября 2010

Вы сделали лучшее.

(Нет более простого способа обойти это, чем добавление шести добавленных вами символов. Даже без неявных преобразований F # короче, чем C #,и изменение дельты от int-к-BigInteger также меньше в F #, чем в C #. Так что не печальтесь о потере неявного преобразования - радуйтесь всем остальным кратким победам. :))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...