2010-11-02 5 views
4

ce code F Tenir compte # pour résumer les chiffres ci-dessous i multiples de 3 et 5:Y a-t-il des astuces pour effectuer des conversions implicites en F #?

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

let sequenceOfMultiples i = 
    seq {1 .. i - 1} |> Seq.filter isMultipleOfThreeOrFive 

Depuis i est un int, vous débordez si i est grande. Cette version avec BigInteger prend en charge que:

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

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

Pour convertir la version int à la version BigInteger, je devais ajouter beaucoup de I s après les chiffres. C'est parce que F # ne fait pas de conversions implicites.

Y a-t-il un moyen facile de contourner ce problème, ou était d'ajouter I s dans 6 endroits la meilleure chose à faire?

+6

ce n'est pas un bug, il est une fonctionnalité ;-) –

Répondre

5

Vous avez fait la meilleure chose.

(Il n'y a pas de moyen plus simple de le contourner qu'en ajoutant les six caractères que vous avez ajoutés.) Même sans conversions implicites, le F # est plus court que le C#, et le delta change-de-int-à- BigInteger est également plus petit dans F # que C# Donc ne soyez pas triste au sujet de la perte de conversion implicite - soyez heureux de toutes les autres victoires de succinct. :))

+1

Speed perd beaucoup de temps cependant. – leppie

+3

Huh? Le code F # BigInteger et C# BigInteger font-ils le même travail? – Brian

+0

Merci, Brian. Toujours un plaisir à lire vos trucs ici et sur reddit. – user392226

6

Ceci ne répond pas exactement à votre question, mais notez que il est également possible de faire sequenceOfMultiples générique en définissant votre propre littéral numérique:

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" 
Questions connexes