2012-07-02 4 views
2

J'utilise Unquote et je n'ai vu aucun ensemble approximatif. J'ai donc décidé d'en écrire un.Généraliser un nouvel opérateur sur plusieurs types

let inline (=~=) x y = abs x-y < 1.E-10 

Cependant l'opérateur ne soit pas mis en correspondance sur, dites listes

let test = [1;2] =~= [1;2] //---> error 

Est-il possible de déclarer cet opérateur à couler comme (=)?

Ou faudrait-il définir un nouveau traits comme « StructuralEquality-ishness»?

Est-il préférable de définir un nouvel opérateur avec, disons, http://code.google.com/p/fsharp-typeclasses/?

+0

Oui, mais vous ne pouvez pas modifier le type de liste - il est déjà défini. Vous pouvez vérifier (avec ':?') Si le type est une liste, et si c'est le cas, utilisez votre propre définition - mais il n'y a pas de classe de type dans F #. –

Répondre

5

Je ne sais pas Unquote, mais en ce qui concerne la fonction/opérateur approximatif je ne suis pas sûr s'il y a un moyen de l'implémenter avec une comparaison structurelle.

Si vous voulez le faire « à la main », en utilisant une technique (ou astuce) similaire à celui utilisé pour le F # classes de types de projet, voici un exemple:

type Approximate = Approximate with 
    static member inline ($) (Approximate, x:^n  ) = fun (y:^n) -> float (abs (x-y)) < 1.E-10 
    static member inline ($) (Approximate, x:list< ^n>) = 
     fun (y:list< ^n>) -> 
      x.Length = y.Length && (List.zip x y |> List.forall (fun (a,b) -> (Approximate $ a) b)) 
// More overloads 
let inline (=~=) x y = (Approximate $ x) y 
+0

Très bien. Pour mon édification, est-ce que votre bibliothèque contient des bits qui correspondent déjà plus ou moins à cela? – nicolas

+0

Ce projet est juste un projet de démonstration. Le but était de montrer la technique, de ne pas l'utiliser en production (bien que je n'y vois aucun problème). Vous n'avez pas besoin de le lier juste pour l'implémenter, aucune des typeclasses définies ici ne vous aidera dans ce cas particulier, mais si vous êtes intéressé par cette technique, c'est une bonne référence. – Gustavo

3

(je n'ai pas utilisé Unquote si ce ne peut pas être applicable.)

Jetez un oeil à la signature de votre fonction

'a -> 'b -> bool (requires member (-) and member Abs) 

List DOE sn't supporte l'un ou l'autre de ces opérateurs. Oui, votre fonction est générique mais les contraintes empêchent son utilisation avec des listes.

(=), d'autre part, n'a pas de contraintes, ce qui signifie qu'il peut être utilisé avec n'importe quel type. Si votre fonction peut être réécrite pour supprimer les contraintes, elle peut être utilisée de la même façon (mais je ne vois pas comment cela est possible compte tenu de l'utilisation de - et abs - comment voulez-vous qu'un comportement list se comporte avec ces opérateurs?).

+0

= a des contraintes: Égalité – nicolas

+0

Je ne m'attends pas à ce que cet opérateur fonctionne comme il est, mais une version modifiée de celui-ci. La question est de savoir comment soulever cet opérateur de la manière la plus générique. l'opérateur résultant sur liste aurait besoin de ses éléments pour satisfaire les contraintes que vous mentionnez, et donner une liste des résultats produits par l'application de l'opérateur original à chaque élément des deux listes, par exemple – nicolas

+0

@nicolas: Bon point, mais l'égalité est une contrainte assez faible, considérant tous les types sauf ceux décorés de '[]' le satisfont. – Daniel

Questions connexes