Are there tricks for doing implicit conversions in F#?

不打扰是莪最后的温柔 提交于 2019-12-17 21:05:58

问题


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 Is after the numbers. This is because F# doesn't do implicit conversions.

Is there an easy way to get around this, or was adding Is in 6 places the best thing to do?


回答1:


You did the best thing.

(There is not an easier way to "get around" it than by adding the six characters you added. Even without implicit conversions, the F# is shorter than the C#, and the delta change-from-int-to-BigInteger is also smaller in F# than C#. So don't be sad about the loss of implicit conversion - be happy about all the other succinctness wins. :) )




回答2:


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"


来源:https://stackoverflow.com/questions/4075160/are-there-tricks-for-doing-implicit-conversions-in-f

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!