是否有在F#中进行隐式转换的技巧?

use*_*226 5 f#

考虑这个F#代码,将下面的数字相加i为3和5的倍数:

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

let sequenceOfMultiples i =
    seq {1 .. i - 1} |> Seq.filter isMultipleOfThreeOrFive
Run Code Online (Sandbox Code Playgroud)

因为iint,如果i很大,你会溢出.这个版本BigInteger负责:

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

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

要将int版本转换为版本BigInteger,我必须I在数字后添加许多s.这是因为F#不进行隐式转换.

有没有一种简单的方法来解决这个问题,或者I在6个地方添加s是最好的办法?

kvb*_*kvb 7

这并不完全回答您的问题,但请注意,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"
Run Code Online (Sandbox Code Playgroud)


Bri*_*ian 5

你做了最好的事情.

(没有比通过添加你添加的六个字符更容易"绕过"它.即使没有隐式转换,F#也比C#短,而且从int到BigInteger的delta变化也更小在F#中比C#.所以不要为隐含转换的丢失感到难过 - 对所有其他简洁的胜利感到高兴.:))

  • 咦?F#BigInteger和C#BigInteger代码做同样的工作? (3认同)