考虑这个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)
因为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
Run Code Online (Sandbox Code Playgroud)
要将int版本转换为版本BigInteger,我必须I在数字后添加许多s.这是因为F#不进行隐式转换.
有没有一种简单的方法来解决这个问题,或者I在6个地方添加s是最好的办法?
这并不完全回答您的问题,但请注意,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)
你做了最好的事情.
(没有比通过添加你添加的六个字符更容易"绕过"它.即使没有隐式转换,F#也比C#短,而且从int到BigInteger的delta变化也更小在F#中比C#.所以不要为隐含转换的丢失感到难过 - 对所有其他简洁的胜利感到高兴.:))