• [^] # Re: Ocaml et Float

    Posté par . En réponse au journal La recherche en langages de programmation au quotidien. Évalué à 3.

    Pourquoi vous n'avez jamais trouvé un moyen d'éviter d'utiliser les insupportables opérateurs float (+.),(-.),(/.),(*.) ?

    Il y a une proposition pour résoudre ce problème, et offrir bien plus de possibilité, sous la forme de modules implicites. Il y a eu une discussion sur le sujet sur le forum OCaml, et il reste des questions tant théoriques que pratiques (au niveau de l'implémentation) à résoudre avant de voir apparaître le système dans le langage.

    Pour faire simple, l'idée est de passer par des modules de premières classes et, dans le cas de ces opérateurs, de définir, disons, un type de module pour les corps :

    module type CORPS = sig
     type t
     val zero : t
     val one : t
     val add : t -> t -> t
     val sub : t -> t -> t
     val mul : t -> t -> t
     val div : t -> t -> t
    end

    puis à définir, disons une fonction add, qui opère sur n'importe quel corps et des valeurs du support du corps :

    let add (type a) (module M : CORPS with type t = a) x y = M.add x y;;
    val add : (module CORPS with type t = 'a) -> 'a -> 'a -> 'a = <fun>

    Ici le corps à passer en paramètre est explicite et si on utilise l'alternative Batteries à la bibliothèque standard, on peut écrire :

    add (module Float) 2.3 4.5;;
    - : float = 6.8

    L'idée étant de faire du module de première classe un paramètre implicite déterminé automatiquement par le compilateur en fonction du type des paramètres x et y. Ici comme ce sont des float, le compilateur cherchera dans son environnement au moment de l'appel à add un corps sur les float déclaré utilisable comme arguments implicites.

    En attendant, si tu utilises Batteries tu peux écrire ton code sur les flottants via des open locaux :

    let open Float.Infix in 2.3 + 4.5;;
    - : float = 6.8

    voir la définition du module Float.Infix :

    #show_module Float.Infix;;
    module Infix = BatFloat.Infix
    module Infix :
     sig
     type bat__infix_t = float
     val ( + ) : float -> float -> float
     val ( - ) : float -> float -> float
     val ( * ) : float -> float -> float
     val ( / ) : float -> float -> float
     val ( ** ) : float -> float -> float
     val ( -- ) : float -> float -> float BatEnum.t
     val ( --- ) : float -> float -> float BatEnum.t
     val ( =~ ) : ?epsilon:float -> float -> float -> bool
     end

    Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.