• [^] # Re: ouai

    Posté par . En réponse au journal Données vs Code. Évalué à 3. Dernière modification le 29 mars 2016 à 16:42.

    Mon exemple ne marche pas et ça tombe bien car cella montre bien que les classe ocaml ne sont pas comme des classes de poo. T'es bien obligé de changer la signature de validated (comme avec les objets immédiats) pour ne pas qu'il soit considéré comme un sous-type de base.

    (* c'est accepté par le compilo car le type validated est un sous type de base *)
    use_valid_string (new base "invalid")
    (*- : bytes = "invalid" *)
    (* on peut faire *)
    class ['a] validated f i = let _ = if not (f i) then failwith "invalid" in
     object inherit ['a] base i
     method valid = true
    end;;
    let use_valid_string (o : _ validated) = print_endline o#get;;
    use_valid_string (new base "invalid");;
    (*Error: This expression has type bytes base
     but an expression was expected of type bytes validated
     The first object type has no method valid *)
    (* ouf... *)

    On peut aussi combiner avec un phantom type pour un maximum de safety. Attention, si on retire la méthode repr, ça ne marche à nouveau plus.

    class ['a,'b] any repr i =
    object(self)
     (* on est obligé de rendre la representation publique ! *)
     method repr : 'b = repr i
     method get : 'a = i
     end;;
    type 'a valid (* notre type fantome *)
    class ['a, 'b] validated repr i =
    (* ici on force la validation, commenté car i'm lazy *)
    (* let _ = repr i in *)
    object
     constraint 'b = 'a valid
     inherit ['a, 'b] any repr i
    end
    (* on passe au constructeur une fonction qui "valide" en construisant le type fantome *)
    (* le but de cette fonction c'est d'avoir une version spécialisée du constructeur,
     via l'annotation de type sur repr. on peut s'en passser...*)
    let make_validated (repr : 'a -> 'a valid) obj =
     new validated repr obj#get
    let use_validated (o : _ validated) = o#get
    let use_any o = o#get
    let id x = x
    use_validated (new any id "invalid");;
    (*
    Error: This expression has type (bytes, bytes) any
     but an expression was expected of type (bytes, bytes valid) validated
     Types for method repr are incompatible
    *)
    use_validated (make_validated (fun _ -> failwith "i am lazy") (new any id "plain"));;
    (* - : bytes = "plain" *)
    (* et on peut toujours utiliser un string validated pour un string any *)
    use_any (make_validated (fun _ -> failwith "i am lazy") (new any id "plain"));;
    (* - : bytes = "plain" *)

    S'il y en a par ici qui ont une solution pour cacher repr ?