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

Haskell Discussion :

Débutante en Haskell, question sur les types.


Sujet :

Haskell

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 14
    Points : 13
    Points
    13
    Par défaut Débutante en Haskell, question sur les types.
    Je suis inscrite à un cours de programmation qui comporte quelques semaines sur les languages fonctionnels. C'est un cours très rapide qui ne nous laisse pas vraiment le temps de comprendre les subtilités de Haskell que l'on doit utiliser pour réaliser nous travaux. Voici un bout de code que j'essaie de faire fonctionner...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    data Exp = Enum Int   -- Une constante
       | Eplus Exp Exp       -- e1 + e2
       | Etimes Exp Exp      -- e1 * e2
       | Eneg Exp              -- (- e)
       | Egt Exp Exp           -- e1 > e2
       | Enot Exp              -- (not e)
       | Elf Exp Exp Exp       -- if e1 then e2 else e3
    
    data Val = Vnum Int 
       | Vbool Bool 
    
    eval :: Exp -> Val
    eval (Enum n)  = Vnum n
    La partie en noir nous a été donné et il faut implémenter toutes les versions de la fonction "eval" pour tous les types Exp. Je ne tiens pas à ce que personne ne fasse mon devoir au complet mais j'aimerais au moins comprendre comment démarrer.
    La ligne en bleu est celle que j'essaie de composer. Haskell me donne une erreur comme quoi je passe du types Exp -> Int -> Val quand il veut simplement Exp -> Val. Si je fais = n alors il me dit que je retourne juste Int au lieu de Val. J'ai tout essayé mais je n'arrive vraiment pas a lui faire retourné une valeur Val sans passer par un Int.
    Le pire, c'est qu'éventuellement pour réussir "Eplus" par exemple je devrai faire des appels récursifs qui pourrons utiliser l'operateur d'addition (+)... "eval Eplus(Enum 3 Enum 4) qui devra donner 7" mais puisque Val peut être un booléen alors je ne sais vraiment pas comment m'y prendre.

    Merci d'avance, je me sens très perdue...

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Utilise les balises CODE à l'avenir (bouton # de l'interface) sinon l'indentation est perdue et pour un langage comme Haskell c'est fâcheux...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    data Exp = Enum Int -- Une constante
             | Eplus Exp Exp -- e1 + e2
             | Etimes Exp Exp -- e1 * e2
             | Eneg Exp -- (- e)
             | Egt Exp Exp -- e1 > e2
             | Enot Exp -- (not e)
             | Elf Exp Exp Exp -- if e1 then e2 else e3
     
    data Val = Vnum Int
             | Vbool Bool
     
    eval :: Exp -> Val
    eval (Enum n) = Vnum n
    Ce code compile (il est correct après tout ), donc j'aimerais un peu plus de détails, par exemple quel compilateur utilises-tu ?

    La ligne en bleu est celle que j'essaie de composer. Haskell me donne une erreur comme quoi je passe du types Exp -> Int -> Val quand il veut simplement Exp -> Val.
    Cette erreur ressemble beaucoup à celle que tu aurais si tu avais oublié le n final :
    ou un truc comme ça. (Est-ce que tu as bien terminé ton fichier par un passage à la ligne ? Il me semble que Hugs avait des petits problèmes avec ça)

    --
    Jedaï

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 14
    Points : 13
    Points
    13
    Par défaut
    Ah oui, pardon, j'ai copier la mauvaise erreur

    J'utilise WinHugs (donc Hugs)
    Et si dans l'interpreteur je lui demande "Enum 2" par exemple
    Il me répond ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ERROR - Cannot find "show" function for:
    *** Expression : Enum 2
    *** Of type    : Exp
    Aussi, si j'essaie de faire une addition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    eval (Eplus e1 e2)  = (eval e1) + (eval e2)
    Il ne compile plus me disant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ERROR file:.\tp2-5.hs:15 - Instance of Num Val required for definition of eval

  4. #4
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    En Haskell, il y a une classe de type "Show" qui fournit la méthode "show" qui transforme une valeur en sa représentation (une String), cette méthode "show" est utilisée par l'interpréteur pour t'afficher les valeurs.
    Si tu n'as pas envie d'avoir une représentation particulière, demande juste à Haskell de te créer automatiquement une instance standard pour ton type, avec "deriving" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    data Exp = Enum Int -- Une constante
             | Eplus Exp Exp -- e1 + e2
             | Etimes Exp Exp -- e1 * e2
             | Eneg Exp -- (- e)
             | Egt Exp Exp -- e1 > e2
             | Enot Exp -- (not e)
             | Elf Exp Exp Exp -- if e1 then e2 else e3
               deriving (Show, Eq, Ord)
    (Comme tu le vois on peut aussi dériver automatiquement d'autres classes de type, comme Eq (égalité entre valeurs de ce type) et Ord (comparaisons)).

    Maintenant tu peux utiliser ton interpréteur :
    (passionant...)

    Aussi, si j'essaie de faire une addition
    eval (Eplus e1 e2) = (eval e1) + (eval e2)

    Il ne compile plus me disant
    ERROR file:.\tp2-5.hs:15 - Instance of Num Val required for definition of eval
    Num est la classe de type fournissant l'addition (+), et Val n'est pas une instance de cette classe, donc ton code est refusé. Dans ce cas c'est en fait une bonne chose, parce que la logique de ton code est erronée : que fais-tu si e1 ou e2 s'évalue en un Vbool ? La façon correcte de faire est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    eval (Eplus e1 e2) = 
        case (eval e1, eval e2) of
          (Vnum n1, Vnum n2) -> Vnum (n1 + n2)
          _                  -> error $ "You can't add booleans expressions : " ++ show e1 ++ " + " ++ show e2
    Ou un truc comme ça (il peut-être intéressant d'abstraire ce schéma car tu vas le rencontrer pour d'autre cas).

    --
    Jedaï

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 14
    Points : 13
    Points
    13
    Par défaut
    M'ouais! C'est du bon, enfin ca compile.

    Par contre maintenant si j'essaie de le faire fonctionner...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Main> eval Eplus(Enum 2 Enum 3)
     
    ERROR - Type error in application
    *** Expression     : eval Eplus (Enum 2 Enum 3)
    *** Term           : eval
    *** Type           : Exp -> Val
    *** Does not match : a -> b -> c
    X_x.. je n'arrive pas a croire que ceci est notre tout premier devoir après seulement 4 cours en Haskell. C'est vraiment trop compliqué. Et je suis certaine qu'il ne voulait pas qu'on modifie les datatype en ajoutant "deriving" même si, moi aussi, je vois en quoi ca peut etre utile.
    Je m'en arrache les cheveux

  6. #6
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Tu as un problème avec le parenthésage... En Haskell les parenthèses ne servent qu'à grouper, rien à voir avec les paramètres de fonctions (ou de constructeurs, qui ne sont jamais que des fonctions en dehors des motifs).
    Regarde, l'espace signifie "application" et il est associatif à gauche, autrement dit :
    signifie :
    autrement dit : "a appliqué à b, le tout appliqué à c".

    Comme dans ton cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    eval Eplus (Enum 2 Enum 3)
    signifie (eval appliqué à Eplus) appliqué à (Enum 2 Enum 3) (qui lui-même est incorrect...). D'où ton erreur de type...

    Le parenthésage correct est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    eval (Eplus (Enum 2) (Enum 3))
    Et je suis certaine qu'il ne voulait pas qu'on modifie les datatype en ajoutant "deriving" même si, moi aussi, je vois en quoi ca peut etre utile.
    Bof, c'est purement cosmétique à ce niveau, ça montre de la recherche personnelle sur le langage (il n'a pas besoin de savoir que je te l'ai montré) et ça facilite grandement les tests alors...

    --
    Jedaï

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 14
    Points : 13
    Points
    13
    Par défaut
    Ah! Oui! La ca fonctionne Merci de tout coeur!

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

Discussions similaires

  1. Question sur les types fantômes et la compilation
    Par GnuVince dans le forum Caml
    Réponses: 9
    Dernier message: 15/11/2010, 18h40
  2. Réponses: 2
    Dernier message: 28/03/2008, 23h28
  3. petite question sur les types de champs
    Par charlie koller dans le forum Débuter
    Réponses: 2
    Dernier message: 21/02/2007, 17h57
  4. Questions sur les types énumérés
    Par Premium dans le forum Langage
    Réponses: 5
    Dernier message: 12/11/2006, 18h00
  5. [SQL 2000] Question sur les types de données
    Par Angath dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 03/11/2006, 14h05

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