• # Module et type abstrait

    Posté par . En réponse au journal Une petite histoire d'utilisation type fort dans Ocaml. Évalué à 5.

    Il existe un autre moyen, pour éviter les alias entre types structurellement identiques, qui consiste à passer par le système de modules et les type abstraits. Ta solution, bien que résolvant ta problématique, rajoute une indirection en mémoire : tes types sont des pointeurs sur des couples de int (qui n'ont pas la même étiquette et ne sont donc pas identiques). Afin d'éviter ce pointeur, on peut utiliser des modules dans lesquels les types seront directement des couples mais en le cachant au monde extérieur.

    Exemple :

    (* on définit une signature pour un module de coordonnés *)
    module type Coord = sig
     type t
     val make : int -> int -> t
     val to_pair : t -> int * int
    end
    (* on définit deux implémentations identiques *)
    module A : Coord = struct
     type t = int * int
     let make i j = (i,j)
     let to_pair x = x
    end;;
    module A : Coord
    module B : Coord = struct
     type t = int * int
     let make i j = (i,j)
     let to_pair x = x
    end;;
    module B : Coord

    Ici, comme l'interface des modules définit un type t sans rien dire sur lui (on parle de type abstrait), les types A.t et B.t sont incompatibles, bien que structurellement identiques.

    let p = A.make 1 2;;
    val p : A.t = <abstr>
    A.to_pair p;;
    - : int * int = (1, 2)
    (* les types ne sont pas compatibles *)
    B.to_pair p;;
    Error: This expression has type A.t but an expression was expected of type B.t

    Ensuite, il est aisé, à partir des primitives des modules, d'écrire des fonctions de conversions d'un type dans l'autre :

    let a_to_b x = let i,j = A.to_pair x in B.make i j;;
    val a_to_b : A.t -> B.t = <fun>
    let b_to_a x = let i,j = B.to_pair x in A.make i j;;
    val b_to_a : B.t -> A.t = <fun>
    let p1 = a_to_b p;;
    val p1 : B.t = <abstr>
    B.to_pair p1;;
    - : int * int = (1, 2)
    A.to_pair (b_to_a p1);;
    - : int * int = (1, 2)

    P.S : tout système de types, quelque soit le langage, a à voir avec la preuve de programme, mais là c'est une autre histoire. ;-)

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