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 :

[Débutant] Problème un peu bizarre (je sais vraiment pas quoi mettre comme titre là)


Sujet :

Caml

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 32
    Points : 18
    Points
    18
    Par défaut [Débutant] Problème un peu bizarre (je sais vraiment pas quoi mettre comme titre là)
    Me revoilà ^^

    Je sais pas trop comment expliquer mon problème clairement (ni même quel nom lui donner) alors le mieux c'est de montrer des petits bouts de code.

    Voici mon code actuel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    let my_var = get_var () in
    Library.iter_on_var_list (fun var_list ->
      List.iter (fun var ->
        if var == my_var then my_func var_list
      ) var_list
    )
    Or il se trouve que chaque 'var' présente dans les 'var_list' que la fonction 'Library.iter_on_var_list' me permet de parcourir sont uniques, si bien que 'my_func var_list' n'est executé qu'une fois, et donc que je parcours l'ensemble des 'var_list' et effectue le test 'if var == my_var' inutilement un grand nombre de fois.

    Du coup j'aimerai pouvoir écrire un truc du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    let my_var = get_var () in
    let var_list = get_var_list my_var in
    my_func var_list
    Seulement je ne vois pas bien comment d'une part écrire la fonction 'get_var_list' à l'aide de 'Library.iter_on_var_list', encore moins en évitant les exécutions inutiles comme précédemment.

    À la rigueur, vu que je vais enchaîner souvent les 3 instructions ci-dessus, je pourrais commencer par me créer une bonne fois pour toute une liste à partir de 'Library.iter_on_var_list', que je pourrais ensuite manipuler comme je veux. Mais là encore, je ne suis pas sûr de savoir faire ca proprement.

    PS: évidemment, la librairie ne me donne pas accès directement à la liste, je suis donc obligé d'utiliser 'Library.iter_on_var_list'.

  2. #2
    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
    "proprement", c'est tout relatif : tu te trimballes une fonction "iter", qui est impérative par nature et donc chiante à utiliser proprement.

    Tu peux faire ce que tu veux avec des exceptions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    let get_var_list my_var =
      let result = ref None in
      let check var_list =
        if List.exists ((==) my_var) var_list
        then begin
          result := Some var_list;
          raise Exit
        end in
      (try Library.iter_on_var_list check
       with Exit -> ());
      !result
    L'idée : quand on trouve la bonne var_list, on lance une exception et ça arrête l'itération. Dans ce cas on renvoie Some var_list, et si on n'a rien trouvé, None.

    Tu es sûr que c'est bien l'égalité physique (==) que tu veux, et pas la simple égalité (auquel cas (List.mem my_var var_list) suffit dans check) ?

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Points : 2 467
    Points
    2 467
    Par défaut
    Citation Envoyé par bumbolol Voir le message
    Me revoilà ^^

    Je sais pas trop comment expliquer mon problème clairement (ni même quel nom lui donner) alors le mieux c'est de montrer des petits bouts de code.
    [...]
    Le problème est là en fait. Quand on ne comprend pas son problème et qu'on ne peut le nommer, il ne faut pas espérer le résoudre un jour Comme c'est le cas majoritairement, ton problème est conceptuel.

  4. #4
    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 bluestorm
    "proprement", c'est tout relatif : tu te trimballes une fonction "iter", qui est impérative par nature et donc chiante à utiliser proprement.
    Tu peux faire ce que tu veux avec des exceptions
    On peut aussi se passer à la fois de la référence et de l'exception en se servant d'une fonction qui renvoie un booléen par lequel on indique si l'itération doit se poursuivre ou non. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    let iter_bool f =
      let rec loop = function
        | [] -> None
        | x :: t -> let stop, result = f x in
          if stop then result else loop t
      in loop
    Évidemment on s'attend à ce que la fonction iter renvoie unit et non un type 'a option. Mais en détournant un peu sa définition, on se passe donc aussi de la référence (en fait ça donne une fonction qui ressemble de loin à iter et, d'une certaine façon, à une sorte de fold « léger »).

    Exemple (vraiment très basique) d'utilisation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    let valeurs = [1; 2; 12; 4; -100; 18; 7; 5; 90; 3]
    let est_negatif x = if x < 0 then (true, Some x) else (false, None)
     
    let premier_negatif = iter_bool est_negatif valeurs
    De cette façon on maintient malgré l'idée de la fonction iter, avec possibilité d'interruption (cette méthode est d'ailleurs utilisée dans certaines bibliothèques hors de la lib standard d'OCaml).

    Dans le cas de la question posée dans ce fil de discussion, ça devrait donner quelque chose comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    let get_var_list my_var =
      let check var_list =
        if List.exists ((==) my_var) var_list then (true, Some var_list) 
        else (false, None) in
      Library.iter_bool_on_var_list check
    Cordialement,
    Cacophrène

  5. #5
    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
    Cacophrène : il a précisé dans son problème que Library était un module externe auquel il n'a pas accès. J'ai compris l'énoncé comme : la fonction d'itération étant fixée, comment faire ce que je veux ? Dans ce cadre, ta méthode n'est pas utilisable.

    Par ailleurs, je m'attends (mais je n'ai pas mesuré) à ce que la méthode par exception soit nettement plus efficace si le cas d'arrêt est effectivement exceptionnel (grande liste, avec peu de cas d'arrêt) : on a un seul gestionnaire d'exception, au lieu des nombreuses allocations imposées par ta méthode. Ceci dit c'est du détail, qui n'est pas important en général et qui ne doit pas empêcher de coder proprement.

  6. #6
    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 bluestorm
    il a précisé dans son problème que Library était un module externe auquel il n'a pas accès. J'ai compris l'énoncé comme : la fonction d'itération étant fixée, comment faire ce que je veux ? Dans ce cadre, ta méthode n'est pas utilisable
    Effectivement je vois ça en relisant attentivement le premier message. Je n'ai pas fait attention à ce point.

    Citation Envoyé par bluestorm
    Par ailleurs, je m'attends (mais je n'ai pas mesuré) à ce que la méthode par exception soit nettement plus efficace si le cas d'arrêt est effectivement exceptionnel (grande liste, avec peu de cas d'arrêt) : on a un seul gestionnaire d'exception, au lieu des nombreuses allocations imposées par ta méthode
    Ça ne fait presque aucun doute à cause de l'allocation d'un couple à chaque itération, suivie d'un filtrage.

    Hélas, ces nouveaux éléments laissent planer le doute sur la possibilité de résoudre ce problème « proprement » comme le souhaite (à juste titre) bumbolol.

    Cordialement,
    Cacophrène

Discussions similaires

  1. Problème un peu bête mais j'arrive pas a comprendre.
    Par mckilleron dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 15/09/2010, 11h33
  2. Problème de LINK Bizarre !!
    Par Jasmine dans le forum MFC
    Réponses: 24
    Dernier message: 19/03/2004, 15h58
  3. [Débutant] Problème de déconnexion d'une page JSP
    Par amal9 dans le forum Servlets/JSP
    Réponses: 12
    Dernier message: 22/01/2004, 13h40
  4. [débutant] Problèmes avec CRegKey
    Par Pedro dans le forum MFC
    Réponses: 4
    Dernier message: 10/11/2003, 15h28
  5. Réponses: 11
    Dernier message: 02/09/2003, 14h20

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