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 :

Problème d'utilisation de match ~ with


Sujet :

Caml

  1. #1
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 9
    Points : 7
    Points
    7
    Par défaut Problème d'utilisation de match ~ with
    Bonjour à tous,

    Ayant l'habitude de travailler en Java ou C, je viens de découvrir l'OCaml, le langage le plus cruel au monde Bref, de toute façon, je n'ai pas le choix, d'autant plus que j'ai un projet à rendre pour dans un mois.
    On me demande d'imprimer à l'écran un plateau de jeu dont les cases changent de couleur suivant leur type. J'ai donc créé un type case qui peut avoir pour valeur Plaine, Boue ou Vide.
    Pour dessiner ces cases, j'utilise la fonction suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let dessiner_case x y case =
      match case with
        |Plaine -> set_color green;
        |Vide -> set_color black;
        |Boue -> set_color blue;
      fill_circle x y 25
    Dans cette version, ma fonction ne m'affiche que les cases Boue (la dernière possibilité).
    J'ai donc réécrit une fonction dont le code est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    let dessiner_case x y case =
      if case = Plaine then
        set_color green;
      if case = Vide then
        set_color black;
      if case = Boue then
        set_color blue;
      fill_circle x y 25
    Et là, ça marche !
    Ma question : pourquoi la première version de ma fonction ne fonctionne qu'à moitié ?
    Merci d'avance

  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
    let dessiner_case x y case =
      match case with
        |Plaine -> set_color green;
        |Vide -> set_color black;
        |Boue -> set_color blue;
                 fill_circle x y 25
    Voilà ton code indenté comme Caml le comprend

    Tu veux sûrement faire ça (à confirmer par des vrais Camleurs) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let dessiner_case x y case =
      (match case with
        |Plaine -> set_color green
        |Vide -> set_color black
        |Boue -> set_color blue);
      fill_circle x y 25
    ou bien avec begin et end :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    let dessiner_case x y case =
      begin match case with
        |Plaine -> set_color green
        |Vide -> set_color black
        |Boue -> set_color blue
      end;
      fill_circle x y 25
    ---

    EDIT:
    Voire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    let couleur_case c =
      match c with
      | Plaine -> green
      | Vide   -> black
      | Boue   -> blue;;
     
    let dessiner_case x y case =
      set_color (couleur_case case);
      fill_circle x y 25;;

  3. #3
    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 confirme, je n'aurais pas dit mieux.

    Un détail : les ";;" sont obligatoires dans le toplevel (pour qu'il puisse savoir interactivement quand s'arrêter de parser pour évaluer) mais optionnels dans un fichier compilé tant qu'il n'y a pas d'ambiguité, c'est-à-dire tant que la phrase qui suit est délimitée par un mot clé de début de phrase (let, type, exception, module...), et n'est pas une expression quelconque.

    Un exemple vaut mieux qu'un deuxième long discours. Le premier code ci-dessous marche, le deuxième pose problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    let x = foo
    exception Bar
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    let x = foo
    print_endline "Hello World"
    Le deuxième code, qui aurait été valide en ajoutant ";;" après, foo, est interprété comme (let x = (foo print_endline "Hello World")), qui n'est clairement pas ce qu'on veut.

    De toute façon mettre des exceptions pures comme phrase, c'est utile dans le toplevel, mais considéré comme une mauvaise pratique dans un fichier. Pour exécuter une expression de type unit il est plus idiomatique d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    let x = foo
    let () = print_endline "Hello World"

  4. #4
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    expression* ?

    (merci pour ce petit rappel, tiens ça mérite un bon point )
    -- Yankel Scialom

  5. #5
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 9
    Points : 7
    Points
    7
    Par défaut
    J'ai finalement opté pour cette correction :
    Citation Envoyé par Ptival Voir le message
    Tu veux sûrement faire ça (à confirmer par des vrais Camleurs) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let dessiner_case x y case =
      (match case with
        |Plaine -> set_color green
        |Vide -> set_color black
        |Boue -> set_color blue);
      fill_circle x y 25
    ... et bonne nouvelle, ça fonctionne ! Merci beaucoup.
    Je crois que j'ai surtout du mal avec la syntaxe de Caml, si particulière.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    309
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 309
    Points : 928
    Points
    928
    Par défaut
    Pour aider un petit peu avec la syntaxe caml: le point virgule en caml n'a pas la même signification que dans la majorité des langages impératifs. En C par exemple, le ; marque la fin d'une expression. En caml, il faut vraiment le voir comme un séparateur d'expressions. C'est en fait (moralemement du moins) une fonction de type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    val (;) : unit -> 'a -> 'a
    (Je dis moralement, parce que ; contrairement à une fonction *assure* que son premier argument sera exécuté en premier !)

    Dans ton cas donc, quand tu es dans un match, tu n'as pas de raison de mettre un ; en fin de ligne, puisque tu ne sépares pas deux expressions.

    J'espère que ça t'aidera à avoir une intuition d'où mettre les ; en caml (et que ça démystifiera un peu la syntaxe dite "particulière" )

  7. #7
    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
    On peut effectivement considérer que `a ; b` est du sucre syntaxique pour `let () = a in b` (dans la version où on force le type unit, `let _ = ..` dans l'autre) -- ce qui est plus précis, pour l'ordre d'évaluation, qu'une fonction.

    Attention, je chipote, mais pour des raisons purement syntaxiques, je préfère pour ma part mettre des points-virgules après toutes les expressions d'une séquence d'action, même sur la dernière (par exemple dans une boucle for, en mettre un avant le "done"). Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    let () = for i = a to be do
      foo;
      bar;
    done
     
    let x = {
      foo = bar;
      baz = foobar;
    }
    La raison pour laquelle j'ai choisi ce style, c'est ce que c'est celui qui facilite la maintenance, en permettant de traiter tous les éléments de la séquence de façon homogène. Le fait de rajouter un élément de plus ou d'inverser la position de deux éléments est beaucoup plus simple que si on retire le point-virgule final -- et c'est une situation dans laquelle, en pratique, je faisais effectivement beaucoup d'erreurs syntaxiques en modifiant le programme.

    L'inconvénient est que ça ne marche pas à tous les endroits, par exemple si c'est l'expression d'let-toplevel (ça marche pour le let-in, mais je ne suis jamais trop à l'aise pour placer et indenter le "in").

    (Dans l'absolu je pense que le mieux dans ces cas est d'avoir une syntaxe dépendant de l'indentation, pour utiliser le saut de ligne comme marqueur de séquençage sans aucune lourdeur visuelle.)

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

Discussions similaires

  1. [RTFEditorKit] Problème d'utilisation
    Par jean.lamy dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 21/10/2004, 18h30
  2. Problème d'utilisation de Mysql avec dev-c++
    Par Watchi dans le forum Dev-C++
    Réponses: 10
    Dernier message: 06/08/2004, 14h35
  3. [cvs] problèmes d'utilisation
    Par gromite dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 29/06/2004, 17h41
  4. Problème: Requête utilisant NOT IN
    Par fages dans le forum Langage SQL
    Réponses: 4
    Dernier message: 04/05/2004, 10h18
  5. problème d'utilisation avec turbo pascal 7.0
    Par le 27 dans le forum Turbo Pascal
    Réponses: 4
    Dernier message: 03/12/2003, 10h44

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