Consider this F# code to sum the numbers below i
that are multiples of 3 and 5:
let isMultipleOfThreeOrFive n =
(n % 3 = 0) || (n % 5 = 0)
let sequenceOfMultiples i =
seq {1 .. i - 1} |> Seq.filter isMultipleOfThreeOrFive
Since i
is an int
, you'll overflow if i
is large. This version with BigInteger
takes care of that:
let isMultipleOfThreeOrFive n =
(n % 3I = 0I) || (n % 5I = 0I)
let sequenceOfMultiples (i : System.Numerics.BigInteger) =
seq {1I .. i - 1I} |> Seq.filter isMultipleOfThreeOrFive
To convert the int
version to the BigInteger
version, I had to add lots of I
s after the numbers. This is because F# doesn't do implicit conversions.
Is there an easy way to get around this, or was adding I
s in 6 places the best thing to do?
This doesn't exactly answer your question, but note that it's also possible to make sequenceOfMultiples
generic by defining your own numeric literal:
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With