考虑这个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#不进行隐式转换。
是否有一种简单的方法可以解决这个问题,或者在6个地方添加I
是最好的选择?
答案 0 :(得分:6)
这并不完全回答您的问题,但请注意,通过定义您自己的数字文字也可以使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"
答案 1 :(得分:5)
你做得最好。
(没有比通过添加你添加的六个字符更容易“绕过”它。即使没有隐式转换,F#也比C#短,并且delta更改从int到BigInteger F#中的数字也比C#小。所以不要为隐含转换的丢失感到难过 - 对所有其他简洁的胜利感到高兴。:))