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 :

[Caml] - Manipulation de listes et d'enregistrements


Sujet :

Caml

  1. #1
    Futur Membre du Club
    Inscrit en
    Mai 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 5
    Points : 8
    Points
    8
    Par défaut [Caml] - Manipulation de listes et d'enregistrements
    Bonjour!

    J'ai une question concernant la manipulation des listes et des enregistrements avec Caml (programmation fonctionnelle). Plus particulièrement dans un cas comme celui-ci:

    personnes =
    {quartier = 2; secteur= 21;
    liste_personnes =
    [{nom = "Jean"; numero = 10}; {nom = "Phil"; numero = 5};
    {nom = "Marc"; numero = 12}; {nom = "Pierre"; numero = 7}]}

    J'ai un enregistrement qui contient 2 "int" et une liste d'enregistrement qui elle-même contient un type string et un autre int.

    Comment puis-je faire, à l'aide de fonction récursive, pour:
    - "imprimer" (print_string) les noms des personnes une à la suite des autres
    - additionner le total des numéros (ici ça donnerait 34 --> 10+12+5+7)

    Je ne peux prendre pour acquis qu'il y a nécessairement 4 personnes en tout temps dans la liste_personnes évidemment...

    Désolé si c'est vraiment simple mais faut bien commencer à quelque part et là je frappe un os

    Merci à l'avance

  2. #2
    Expert confirmé Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 619
    Points : 4 352
    Points
    4 352
    Par défaut
    Facile
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    let fun lis ->
    let rec aux = fun liste somme -> 
     match liste with [] -> somme
                       |((nom,valeur)::r) -> begin
                                                    print_string nom;
                                                    aux r somme+valeur;
                                                    end
    in aux lis 0
    Je ne suis pas tout à fait sûr de la syntaxe, mais en gros c'est ça.
    La fonction devrait afficher les noms, et te renvoyer la somme.
    Elle est récursive, et devrait fonctionner pour toute taille de liste.

    Par contre je ne sais plus gérer les enregistrements, donc là je te l'ai fait pour une liste de (string * int ).

  3. #3
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonjour,

    Il suffit d'utiliser un itérateur de type List.fold_left, comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let afficher_compter personnes =
      List.fold_left (fun x {nom = str; numero = y} ->
        print_string str;
        x + y
      ) 0 personnes.liste_personnes
    Attention : de manière générale il peut être bon de se demander pourquoi on fait des effets de bord dans un itérateur. Je ne sais bien évidemment pas quel est le contexte mais parfois c'est une question fondée.

    Cordialement,
    Cacophrène

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 147
    Points : 102
    Points
    102
    Par défaut
    Désolé, je me permets de faire un petit hors-sujet mais uniquement parce que la réponse a été fournie.

    De façon général, est-il plus performant de faire un fold_left ou un fold_right ?

  5. #5
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Salut,

    Citation Envoyé par dest
    De façon général, est-il plus performant de faire un fold_left ou un fold_right ?
    Je ne te donne pas la réponse mais le code source du fichier list.ml devrait te donner une piste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let rec fold_left f accu l =
      match l with
        [] -> accu
      | a::l -> fold_left f (f accu a) l
    
    let rec fold_right f l accu =
      match l with
        [] -> accu
      | a::l -> f a (fold_right f l accu)
    Cordialement,
    Cacophrène

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 147
    Points : 102
    Points
    102
    Par défaut
    Je dirais que c'est fold_left le plus performant mais j'ai des difficultés pour le justifier.
    L'empreinte mémoire du fold_right m'a l'air plus élevé car il faut descendre très bas pour atteindre la liste vide et enfin remonter le futur résultat.
    Pour le fold_left, on retourne quasiment tout de suite le résultat de la fonction f donc il n'y a pas besoin de descendre trop profondément.

  7. #7
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonjour,

    fold_left est tailrec, fold_right non. Donc, non seulement fold_left sera globalement plus efficace, mais fold_right échouera sur de grandes listes.

    Cordialement,
    Cacophrène

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 147
    Points : 102
    Points
    102
    Par défaut
    Citation Envoyé par Cacophrene Voir le message
    Bonjour,

    fold_left est tailrec, fold_right non. Donc, non seulement fold_left sera globalement plus efficace, mais fold_right échouera sur de grandes listes.

    Cordialement,
    Cacophrène
    Je dois avoir quelques fold_right en stock à modifier par des fold_left

    Merci.

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Souvent, List.fold_right est plus naturelle à utiliser (c'est le "fold" canonique sur les listes); dans ce cas, je préfère l'utiliser, quitte à modifier sa définition pour limiter son utilisation de la pile si le besoin s'en fait sentir. Par contre, j'utilise toujours fold_left quand ça n'enlaidit pas le code.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme manipulation de listes!
    Par galford dans le forum VB 6 et antérieur
    Réponses: 22
    Dernier message: 19/12/2006, 19h50
  2. liste deroulante et enregistrements
    Par poube31 dans le forum Access
    Réponses: 3
    Dernier message: 24/07/2006, 22h54
  3. [VBA-E] Manipuler une liste de Validation
    Par Ptit Dark dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 08/06/2006, 16h28
  4. Manipuler des listes d'objet ?
    Par xla99 dans le forum Général Python
    Réponses: 4
    Dernier message: 06/06/2006, 15h06
  5. [PDFBox]Comment manipuler une LIST
    Par marcotop dans le forum Documents
    Réponses: 11
    Dernier message: 27/08/2004, 15h46

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