IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Caml Discussion :

comment faire un "monType_to_file" et "file_to_monType" ?


Sujet :

Caml

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut comment faire un "monType_to_file" et "file_to_monType" ?
    Bonjour,

    je suis en train d'écrire un programme avec une structure de donnée de la sorte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    type monRecord = { a : float; b : bool; c : string; }
    type qualite = [ `Douteux | `Valable of monRecord ]
    puis je travaille sur des listes de monRecord :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    let u = [ `Douteux ; `Valable { a=3.14159 ;b= true ;c= "NimporteKwa" } ; 
    (* très *) `Douteux (* etc *) }
    je voudrais stocker ces listes dans des fichiers et les relire par la suite.

    Pour l'instant j'ai créé des fonctions de filtrages et je convertis en "Strings", mais c'est très laborieux...

    Quel est le moyen le plus simple ?

    Merci d'avance

  2. #2
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  3. #3
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut
    Ok je ne connaissais pas je vais regarder

    merci de l'info ...

  4. #4
    Inactif  
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    1 958
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Par défaut
    Tabarnak -_-

    T'aurais pu le dire avant...


    Tabarnak...

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 32
    Par défaut sexplib
    Il y a aussi la SExpLib de Markus Mottl qui est assez sexy,
    elle convertit des expressions OCaml en S-expressions (ASCII)

    http://www.ocaml.info/home/ocaml_sources.html

    sur la même page il y a 'sexplib' (aucune dépendance) et 'sexplib310' qui requiert 'type-conv' (dispo sur la même page)

    voici ce que ça donne avec ton type:
    Code ocaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    type monRecord = { a : float; b : bool; c : string; }
    with sexp
     
    type qualite = [ `Douteux | `Valable of monRecord ]
    with sexp
     
    type u = qualite list
    with sexp
     
    let () =
      let u =
        [ `Douteux; `Valable { a=3.14159; b= true; c= "NimporteKwa" } ]
      in
      let u_sexp = sexp_of_u u in
      let u' = u_of_sexp u_sexp in 
      assert (u = u');
     
      Format.printf "u_sexp:\n %a@\n@\n" pp u_sexp;
     
      let str_u_sexp = Sexp.to_string u_sexp in
      Printf.printf "str_u_sexp:\n %s\n" str_u_sexp;
     
      let u'' = u_of_sexp(Sexp.of_string str_u_sexp) in
      assert(u = u'');
    ;;

    et voici ce qui sera affiché par ce bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    str_u_sexp:
     (Douteux(Valable((a 3.1415899999999998826)(b true)(c NimporteKwa))))
    u_sexp:
     (Douteux(Valable((a 3.1415899999999998826)(b true)(c NimporteKwa))))
    Pour ce qui est du module Marshal, il n'est pas garantit qu'il assure la compatibilité descendante car comme il est écrit dans le manuel la compatibilité n'est assurée que pour "a given version of Objective Caml".
    Je pense qu'en revanche la Sexplib a pour ambition de garder une bonne compatibilité sur le long terme.

  6. #6
    Membre Expert
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Par défaut
    Honnêtement, t'emmerde pas avec des jouets douteux... surtout quand je vois des flottant convertis en string pour être éventuellement reconvertis en flottant : du gros n'importe quoi !

    Marshall, c'est du solide.

    Si on voulait le faire proprement, il faudrait s'écrire sa propre fonction de conversion, et donc, entre autres, une fonction de conversion/décomposition des flottants vers du binaire écrit dans un fichier et indépendant de l'endianness.

  7. #7
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut
    J'ai aussi trouvé ceci : JSON

    http://martin.jambon.free.fr/json-wheel.html

    l'avantage que j'y vois pour mon besoin, c'est de générer des fichiers "human-readable", et donc modifiables à la main.

    C'est une approche complémentaire au Marshall.


    merci à fhgfjgfgj de m'avoir rendu attentif à cette limitation :
    Pour ce qui est du module Marshal, il n'est pas garantit qu'il assure la compatibilité descendante car comme il est écrit dans le manuel la compatibilité n'est assurée que pour "a given version of Objective Caml".
    Je pense qu'en revanche la Sexplib a pour ambition de garder une bonne compatibilité sur le long terme.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 32
    Par défaut
    Citation Envoyé par InOCamlWeTrust Voir le message
    Honnêtement, t'emmerde pas avec des jouets douteux... surtout quand je vois des flottant convertis en string pour être éventuellement reconvertis en flottant : du gros n'importe quoi !
    convertir des flottants en string et inversement est tout à fait possible sans perte
    tu aurais dut suivre le thread très récent sur la liste OCaml : "Strange behaviour of string_of_float",
    notament dans un post du Docteur Jon D. Horrop, consultant de la Grenouille Volante :

    > Yes, you wouldn't expect it to be, because the string is an
    > approximate base 10 representation of the float...

    That is not true. All finite floats have exact finite decimal representations.
    So it is perfectly reasonable to expect the conversions to recover the
    original number exactly.
    pour ceux qui auraient du mal avec l'anglais : les flottants sont une représentation sur un nombre de bits finits, et donc ont chacun une représentation décimale finie.

    D'ailleur ce sera probablement l'exemple qui t'aura induit en erreur, en testant dans le top-level on s'apperçoit qu'en dépit des apparence il est parfaitement exact :

    # 3.14159 = (float_of_string "3.1415899999999998826") ;;
    - : bool = true

    Rappelont que les floats ocaml sont les doubles du C, càd double précision floats, flottants en double précision donc qui ont 52 bits de mantisse. Quelqu'un de doué en binaire et en math pourra surement nous démontrer combien de chiffres en base 10 seront nécessaires pour avoir l'exacte représentation du flottant binaire.

    la sexplib semble utiliser (Printf.sprintf "%.20G") comme fonction de convertion.

    Citation Envoyé par InOCamlWeTrust Voir le message
    Marshall, c'est du solide.
    Pour une version donnée d'OCaml comme le dis le manuel.
    Question à 100 euros, si demain la prochaine version d'OCaml change le format de marshaling, comment convertit-on alors les fichiers ?

    Citation Envoyé par InOCamlWeTrust Voir le message
    Si on voulait le faire proprement, il faudrait s'écrire sa propre fonction de conversion, et donc, entre autres, une fonction de conversion/décomposition des flottants vers du binaire écrit dans un fichier et indépendant de l'endianness.
    pour écrire un float en binaire dans un fichier, la fonction est présente dans la extLib, donc ne perdez pas non plus de temps à l'écrire. (sinon tant que j'y suis Int64.bits_of_float donnera le même résultat sur une machine little ou big endian)


    Citation Envoyé par SpiceGuid Voir le message
    À ma connaissance seul Marshall est capable de bien gérer les données cycliques.
    effectivement je confirme, je viens de faire un test avec sexplib

    Citation Envoyé par SpiceGuid Voir le message
    Personnellement je ne vois pas vraiment de raisons d'utiliser un mécanisme "externe" si Marshall peut faire l'affaire.
    déjà pour assurer la compatibilité descendante, et ensuite la tendance actuelle est plutôt d'utiliser des formats de fichier en texte brute, qui offrent de nombreux avantages dont je vous épargne la liste

  9. #9
    Membre confirmé
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Par défaut
    Citation Envoyé par fgjdfgjdgj Voir le message
    Il y a aussi la SExpLib de Markus Mottl qui est assez sexy,
    elle convertit des expressions OCaml en S-expressions (ASCII)

    http://www.ocaml.info/home/ocaml_sources.html

    sur la même page il y a 'sexplib' (aucune dépendance) et 'sexplib310' qui requiert 'type-conv' (dispo sur la même page)
    ça parait intéressant aussi ...

    voici ce que ça donne avec ton type:
    Code ocaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    type monRecord = { a : float; b : bool; c : string; }
    with sexp
     
    type qualite = [ `Douteux | `Valable of monRecord ]
    with sexp
     
    type u = qualite list
    with sexp
     
    let () =
      let u =
        [ `Douteux; `Valable { a=3.14159; b= true; c= "NimporteKwa" } ]
      in
      let u_sexp = sexp_of_u u in
      let u' = u_of_sexp u_sexp in 
      assert (u = u');
     
      Format.printf "u_sexp:\n %a@\n@\n" pp u_sexp;
     
      let str_u_sexp = Sexp.to_string u_sexp in
      Printf.printf "str_u_sexp:\n %s\n" str_u_sexp;
     
      let u'' = u_of_sexp(Sexp.of_string str_u_sexp) in
      assert(u = u'');
    ;;
    Mais moi j'ai du rater quelque chose car dans le TopLevel, sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type monRecord = { a : float; b : bool; c : string; }
      with sexp;;
    je récupère sur le with ...

    Je suppose qu'il faut que je fasse une manip pour faire comprendre le with au TopLevel ?

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 32
    Par défaut
    Citation Envoyé par james-mi Voir le message
    ça parait intéressant aussi ...

    Mais moi j'ai du rater quelque chose car dans le TopLevel, sur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type monRecord = { a : float; b : bool; c : string; }
      with sexp;;
    je récupère sur le with ...

    Je suppose qu'il faut que je fasse une manip pour faire comprendre le with au TopLevel ?
    Télécharge sexplib, lance "make", puis rends toi dans le répertoire lib_test/

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo