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 :

Mauvaise imbracation des if


Sujet :

Caml

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2009
    Messages : 53
    Points : 57
    Points
    57
    Par défaut Mauvaise imbracation des if
    Bonsoir, voilà j'ai un souci qui me fait croire à une mauvaise imbrication des if else if else.

    Si quelqu'un pouvait expliquer un peu la philosophie de la prog fonctionnelle à ce niveau et l'application à ocaml.
    Il y a des moments où je ne vois vraiment pas comment traduire ce que je pense fonctionnellement enfin en Ocaml surtout.
    Comment écrire cette partie proprement en ocaml en supprimant par la même occasion l'erreur bien entendu
    Code : 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
     
    let print_int_zipper (p ,l) =
      let rec aux = function
        |[] -> ()
        |e::ls -> print_int e; print_string "; "; aux ls in
      print_string " ["; aux p ;
      print_string "] * ["; aux l; print_char ']';
      print_newline()
     
    let read_char () =
      let c = String.get (read_line()) 0
     
    print_char (read_char());
    let lz = ([], [2;3;4;5;6;7;8;9])
    print_int_zipper lz;
    while (true) do
        let c = read_char () in
        if c = 'd' then begin
          a_d lz ; print_int_zipper lz end
        else begin if c = 'g' then begin
            a_g lz ; print_int_zipper lz end
        else
            print_int_zipper lz end
    done ;; (* ligne 42 *)
    Erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    File "zipper.ml", line 42, characters 5-7:
    Error: Syntax error
    Pour info c'est un fichier sur la structure de donnée zipper.
    Je veux pouvoir naviguer sur ces structures via des commandes g:gauche, d:droite x:surplace etc... Et de voir après chaque opération, ma position.
    Pour le moment c'est un zipper de liste juste après se trouve la définition pour les arbres binaires et les forets sans la posibilité de naviguer pour le moment.

  2. #2
    Membre actif
    Avatar de Ptival
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2004
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2004
    Messages : 70
    Points : 276
    Points
    276
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    let print_int_zipper (p ,l) =
      let rec aux = function
        |[] -> ()
        |e::ls ->
          print_int e;
          print_string "; ";
          aux ls
      in
      print_string " [";
      aux p ;
      print_string "] * ["; aux l; print_char ']';
      print_newline ()
    Première remarque ici : pour appliquer un traitement impur à tous les éléments d'une liste, il existe une fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    List.iter : ('a -> unit) -> 'a list -> unit
    Donc, rien ne sert de réinventer la roue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    let print_int_list = List.iter (fun x -> print_int x; print_string "; ")
     
    let print_int_zipper (p ,l) =  
      print_string " [";
      print_int_list p;
      print_string "] * [";
      print_int_list l;
      print_char ']';
      print_newline ()
    Ensuite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    let read_char () =
      let c = String.get (read_line ()) 0
    Pourquoi pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    print_char (read_char());
    let lz = ([], [2;3;4;5;6;7;8;9])
    print_int_zipper lz;
    while (true) do
        let c = read_char () in
        if c = 'd' then begin
          a_d lz ; print_int_zipper lz end
        else begin if c = 'g' then begin
            a_g lz ; print_int_zipper lz end
        else
            print_int_zipper lz end
    done ;; (* ligne 42 *)
    Alors là c'est du grand délire... Pourquoi est-ce ce code est à top-level ? Pourquoi est-ce qu'il manque des "in" après des "let" ?
    Admettons que ce soit vraiment ce que tu veux qu'il se passe durant l'exécution :

    Code : 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
     
    let _ =
      print_char (read_char()); (* Affiche à l'utilisateur le premier caractère qu'il va taper *)
      let lz = ([], [2;3;4;5;6;7;8;9]) in (* Il te manque ce "in" dans ton code *)
      print_int_zipper lz; (* Devrait afficher la liste ci-dessus *)
      while (true) do
        let c = read_char () in
        if c = 'd'
        then begin
          a_d lz ; print_int_zipper lz
        end else begin
          if c = 'g'
          then begin
            a_g lz ;
            print_int_zipper lz
          end else begin
            print_int_zipper lz
          end
        end
      done
    Cela devrait marcher. Note que l'indentation sert à voir si on a bien fermé ses couples begin/end. Personnellement, je préfère même écrire plutôt dans ce style :

    Code : 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
     
    let _ =
      print_char (read_char());
      let lz = ([], [2;3;4;5;6;7;8;9]) in
      print_int_zipper lz;
      while (true) do
        let c = read_char () in
        if c = 'd'
        then (
          a_d lz ;
          print_int_zipper lz
        )
        else if c = 'g'
        then (
          a_g lz ;
          print_int_zipper lz
        )
        else (
          print_int_zipper lz
        )
      done
    Mais d'autres préfèrent les begin/end et les imbrications !

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2009
    Messages : 53
    Points : 57
    Points
    57
    Par défaut
    Parfait merci tou fonctionne mieux.
    le let x in ce n'est pas uniquement quand x n'est pas unit ?
    De plus une explication pour let "let _ =" please ?

    Edit: Je préfère le style parenthésé aussi plus "fonctionnel" et me fait oublier VBA.

  4. #4
    Membre actif
    Avatar de Ptival
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2004
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2004
    Messages : 70
    Points : 276
    Points
    276
    Par défaut
    Il y a toujours un in après un let. D'ailleurs ta remarque est bizarre au vu de ton erreur (le type n'était pas unit).

    Quant au "let _ = ", c'est pas vraiment nécessaire ici je crois.
    En général, lorsque tu écris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let plop = foo; bar; baz
    Le compilateur va gueuler si foo et bar ne sont pas de type unit : il va te dire "attention, foo/bar renvoie une valeur de type some_type et tu ne t'en es pas servi !".
    Du coup, tu peux indiquer au compilateur que tu es au courant de ce que tu fais en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    let plop =
      let _ = foo in
      let _ = bar in
      baz
    D'ailleurs, tu aurais aussi le droit d'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    let plop =
      let _ = foo in
      let _ = bar in
      let () = baz in (* le motif () est valide si baz a bien le type unit *)
      ()
    Enfin bref, ce sont des détails, et tu peux sans doute enlever la ligne "let _ = " sans causer de préjudice à ton programme... C'est juste une de mes habitudes...

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2009
    Messages : 53
    Points : 57
    Points
    57
    Par défaut
    Ok merci.
    Ma remarque concernait mes hésitations et idées impressions.
    Et suite à tes explications tout semble plus claire.

    Par ailleurs si tu fais allusion au let lz = [], ... sans le in
    c'est tout simplement parce que je suis dans un fichier et j'ai considéré que si celui ci sera interpreter comme un module je n'ai pas besoin de in (Comme dans les modules).
    Puisque partout j'ai défini des fonctions sans in je me suis dit que c'était possible d'en faire de même avec des variables. Et ca compile sans problème.

    Seulement, appartenant à un contextes précis, la methode let _ = est très bien.
    D'ailleurs j'ai remanier la chose avec un nom : testZipperList () =
    et tout en bas, selon le zipper que je souhaite tester; let _ = testZipperX () ;
    Et c'est parfait.
    Merci beaucoup.

  6. #6
    Membre actif
    Avatar de Ptival
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2004
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2004
    Messages : 70
    Points : 276
    Points
    276
    Par défaut
    Tiens d'ailleurs quand je dis qu'il y a toujours un "in" après un "let", effectivement ça n'est pas le cas pour des déclarations top-level (dans ta boucle interactive ou dans ton fichier .ml). Donc tu as le droit d'écrire à top-level "let foo = bar".

    Dans ce cas je comprends ce que tu avais voulu écrire.

    D'ailleurs, en recopiant ton code initial, je ne vois pas d'erreur syntaxique dans :

    Code : 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
    while (true) do
      let c = read_char () in
      if c = 'd'
      then
        begin
          a_d lz ;
          print_int_zipper lz
        end
      else
        begin
          if c = 'g'
          then
            begin
              a_g lz ;
              print_int_zipper lz
            end
          else
            print_int_zipper lz
        end
    done
    Peut-être qu'il faut sauter une ligne entre les déclarations top-level dans un fichier ?

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2009
    Messages : 53
    Points : 57
    Points
    57
    Par défaut
    Je ne voyais pas l'erreur non plus d'où ma demande sur le forum
    Mais ce n'est pas grave ta solution est vraiment esthétique par rapport à mon code.

  8. #8
    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,

    Citation Envoyé par Ptival
    Peut-être qu'il faut sauter une ligne entre les déclarations top-level dans un fichier ?
    Dès qu'il y a un point-virgule unique à la fin d'une instruction, OCaml attend une suite même s'il y a des sauts de ligne, comme ici par exemple où l'on ne définit pas deux fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    let print_bar () = print_endline "bar";
    
    
    let print_foo () = print_endline "foo"
    C'est peut-être quelque chose comme ça qui a déclenché une erreur au niveau du done.

    Cordialement,
    Cacophrène

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2009
    Messages : 53
    Points : 57
    Points
    57
    Par défaut
    En fait on était qu'à la première partie du fichier il y avait du contenu après.
    Et j'ai enlevé le ";", j'en ai mis 2 etc... Rien à faire.

  10. #10
    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
    Je n'ai pas suivi, l'erreur de syntaxe est-elle encore d'actualité et, si oui, quel est le code complet qui pose problème ?

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

Discussions similaires

  1. [FLASH 5] Mauvaise qualité des captures d'écran
    Par fredhali2000 dans le forum Flash
    Réponses: 1
    Dernier message: 11/08/2006, 14h53
  2. [GD] Mauvaise qualité des textes en jpeg
    Par coolmic dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 26/05/2006, 18h15
  3. firefox - mauvaise gestion des passwords
    Par photorelief dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 10/06/2005, 09h02
  4. Réponses: 2
    Dernier message: 19/10/2004, 09h55
  5. Réponses: 3
    Dernier message: 04/09/2002, 09h42

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