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 :

add an instance declaration for (RealFrac Int)


Sujet :

Haskell

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    mai 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2006
    Messages : 113
    Points : 64
    Points
    64
    Par défaut add an instance declaration for (RealFrac Int)
    Insoluble pour un débutant, j'ai tout essayé.
    Voici le code :
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
     
    import Data.Monoid
    import System.IO
    import System.Random
    import Graphics.Gloss
     
    larg = 320
    haut = 200
     
    minX = fromIntegral -2.4
    maxX = fromIntegral 2.4
    minY = fromIntegral -1.5
    maxY = fromIntegral 1.5
     
    rc = [ (minX + (maxX - minX)`div`larg * x) | x <- [0,1..319]]
    ic = [ (minY + (maxY - minY)`div`haut * y) | y <- [0,1..199]]
     
    x = [0,1..319]
    y = [0,1..199]
     
    main = do
            let rz = 1
            let iz = 0
    	affiche rz iz
    	main
     
    affiche rz iz = display  
    	 (InWindow
    	       "Simple Mandel" 	 -- window title
    		(320, 200) 	 -- window size
    		(10, 10)) 	 -- window position 20
             black                   -- background color
             (picture rz iz)     -- picture to display
     
    picture rz iz = pictures (listOfPoints n rz iz r i temoin c l m)
       where
         n = 1920
         r = 0
         i = 0
         temoin = 0
         c = 1
         l = 0
         m = 0
    listOfPoints 0 _ _ _ _ _ _ _ _ = []
    listOfPoints n rz iz r i temoin c l m = point : listOfPoints (n-1) rz' iz' r' i' temoin' c' l' m' 
        where
    	r' = rz
    	i' = iz
    	c' = comptec  c n
    	l' = comptel l c
    	rz' = r'*r' - i'*i' + (rc !! (l'))
    	iz' = 2*r'*i' + (ic !! (c'))
    	temoin' = (rz'*rz' + iz'*iz')
    	m' = fixem temoin'
    	point = choixp c' l' m'
     
    fixem temoin'
    	|temoin' > 4 = 5
    	|temoin' <= 4 = 3
     
    comptec c n
    	|n`mod`200 <= 0 = c+1
    	|n`mod`200 > 0 = c 
     
    comptel l c
    	|c`mod`200 <= 0 = l+1
    	|c`mod`200 > 0 = l
     
    choixp n c' l' m'
    	|m' > 4 = translate (x !! (l')) (y !! (c')) (color (myColor(n/2)) (circle (1.0)))
    	|m' <= 4 = translate (0) (0) (color red (circle (1.0)))
     
    myColor n = ( [ca,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp] !! (round(n/120)) )
     
    ca = white
    cb = light(light yellow)
    cc = light yellow
    cd = yellow   
    ce = light(light orange)
    cf = light orange
    cg = orange
    ch = light (dark orange)
    ci = light red
    cj = red
    ck = dark red 
    cl = light violet
    cm = violet
    cn = light(light (dark violet))
    co = light ( dark violet)
    cp = blue
    Et voici le message :
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    SimpleMandel.hs:34:27:
        Couldn't match type `a2 -> Picture' with `Picture'
        Expected type: [Picture]
          Actual type: [a2 -> Picture]
        In the return type of a call of `listOfPoints'
        In the first argument of `pictures', namely
          `(listOfPoints n rz iz r i temoin c l m)'
        In the expression: pictures (listOfPoints n rz iz r i temoin c l m)
    
    SimpleMandel.hs:54:17:
        Could not deduce (RealFrac Int) arising from a use of `choixp'
        from the context (Integral a, Num a3, Ord a3)
          bound by the inferred type of
                   listOfPoints :: (Integral a, Num a3, Ord a3) =>
                                   a
                                   -> (a1 -> b0)
                                   -> (a1 -> b0)
                                   -> (a1 -> b0)
                                   -> (a1 -> b0)
                                   -> (a1 -> b0)
                                   -> Int
                                   -> Int
                                   -> Int
                                   -> [a3 -> Picture]
          at SimpleMandel.hs:(43,1)-(54,31)
        Possible fix: add an instance declaration for (RealFrac Int)
        In the expression: choixp c' l' m'
        In an equation for `point': point = choixp c' l' m'
        In an equation for `listOfPoints':
            listOfPoints n rz iz r i temoin c l m
              = point : listOfPoints (n - 1) rz' iz' r' i' temoin' c' l' m'
              where
                  r' = rz
                  i' = iz
                  c' = comptec c n
                  l' = comptel l c
                  ....
    Comment faire ?

  2. #2
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : avril 2013
    Messages : 610
    Points : 1 880
    Points
    1 880
    Billets dans le blog
    21
    Par défaut
    Il manque la fonction 'pictures' pour comprendre l'erreur.
    Ce que dit le compilateur c'est qu'il reçoit une liste de fonctions (a2 -> Picture) plutôt que la liste de Picture qu'il attend.
    Mais cette liste est renvoyée par la fonction pictures, qui n'est pas dans l'extrait que tu envoies...

    Une bonne pratique en Haskell (qui améliore souvent l'intelligibilité et la pertinence des messages d'erreur) est d'accompagner chaque fonction de son type, avec la syntaxe
    function :: arg1Type -> arg2Type ... -> argNType -> returnType
    Il n'est pas toujours pertinent de mettre un type concret (ex: Integer), il est aussi possible de mettre un type polymorphique (ex: a)

    Pour le second message d'erreur, il vient de l'utilisation de la fonction 'round' (dans myColor, je présume) qui exige que son premier argument appartienne à la classe de type 'RealFrac'; en l'absence de typage explicite de tes fonctions, le compilateur n'a pas pu s'en assurer. Là encore, je pense qu'un typage explicite permettrait de lever l'erreur. Ou bien pour conserver un certain degré de polymorphisme, ajouter un condition de type à ta fonction
    ex: maFonction :: (RealFrac a) => a -> b -> c

    Au passage, le typage des fonctions permet aussi souvent d'améliorer la rapidité du code. Le compilateur considère en général qu'un nombre entier est de type Integer (c'est-à-dire arbitrairement grand) tandis que souvent un Int est suffisant et nettement plus rapide (c'est un type 'machine'). Mais il n'utiliser un Int que si le type de la fonction lui dit de le faire.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    mai 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2006
    Messages : 113
    Points : 64
    Points
    64
    Par défaut
    Voir la ligne 34 !
    picture rz iz = pictures ...
    J'ai bien compris la demande de donner instance RealFrac, ce que j'aurais aimé c'est que l'on m'indique ou et comment dans mon code.
    Mes autres programmes de fractales sur le même canevas marchent sans problème.

  4. #4
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : avril 2013
    Messages : 610
    Points : 1 880
    Points
    1 880
    Billets dans le blog
    21
    Par défaut
    Voir la ligne 34 !
    picture rz iz = pictures ...
    ligne 34 il y a 2 fonctions différentes (picture et pictures) et la fonction pictures ne me semble pas définie dans le code que tu donnes?
    J'ai bien compris la demande de donner instance RealFrac, ce que j'aurais aimé c'est que l'on m'indique ou et comment dans mon code.
    Comme je te le disais, c'est dans la déclaration de type de tes fonctions que tu peux faire apparaître ce genre de contraintes. Dans ton code il n'y en a pour l'instant aucune!
    Les déclarations de type se font de la façon suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    -- type concret:
    increment :: Int -> Int 
    increment a = a+1
     
    --type abstrait (avec condition de type):
    increment :: (Num a) => a -> a
    increment a = a + 1

  5. #5
    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 560
    Points
    8 560
    Par défaut
    Les problème sont doubles, la "nécessité" de RealFrac est dû à ton usage de l'opérateur (/) et la fonction round qui représente une vraie division et un arrondissement, si tu veux le quotient d'une division euclidienne, il faut utiliser div à la place (et comme tu manipule des entiers, tu ne peux pas faire de "vraie" division, du moins pas sans convertir) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    choixp n c' l' m'
    	|m' > 4 = translate (x !! (l')) (y !! (c')) (color (myColor(n `div` 2)) (circle (1.0)))
    	|m' <= 4 = translate (0) (0) (color red (circle (1.0)))
     
    myColor n = ( [ca,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp] !! (n `div` 120)) )
    Note que j'utilise `div`comme un opérateur, ceci est possible pour toute fonction à deux arguments, de même que tout opérateur peut être utilisé comme une fonction en l'entourant de parenthèses comme "(+) 5 3".
    Je suggère également que tu devrais utiliser mod pour garantir que tu n'auras pas d'indice trop grand pour la taille de ta liste de couleurs.

    Plus généralement, il est fréquent que l'absence d'une instance traduise que tu n'as pas utilisé la bonne opération plutôt qu'un réel manque à corriger en écrivant une instance (ici de RealFrac pour Int, comme si cela avait du sens d'implémenter round, truncate etc pour Int...).

    L'autre erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Couldn't match type `a2 -> Picture' with `Picture'
        Expected type: [Picture]
          Actual type: [a2 -> Picture]
        In the return type of a call of `listOfPoints'
        In the first argument of `pictures', namely
          `(listOfPoints n rz iz r i temoin c l m)'
        In the expression: pictures (listOfPoints n rz iz r i temoin c l m)
    dit exactement ce qui pose problème : pictures attend une liste de Picture ("Expected type" par le contexte) mais (listOfPoints n rz iz r i temoin c l m) est une liste de fonctions de type "a -> Picture" ("Actual type" de l'expression)...

    Comme les attentes de pictures sont raisonnables, c'est donc que le problème se situe dans listOfPoints, clairement il retourne une liste mais les éléments sont des fonctions plutôt que des Pictures. Lorsque "b" est attendu mais que "a -> b" est le type réel c'est souvent simplement que on a oublié de fournir un paramètre à la fonction, regardons donc ici les éléments de (listOfPoints n rz iz r i temoin c l m) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    listOfPoints n rz iz r i temoin c l m = point : listOfPoints (n-1) rz' iz' r' i' temoin' c' l' m'
    donc point qui est défini dans le where :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    point = choixp c' l' m'
    Ok, et la définition de choixp est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    choixp n c' l' m' = ...
    Donc tu passes trois arguments à une fonction de quatre arguments... Tu obtiens donc une fonction plutôt qu'une Picture, logique.

    Comme l'a dit stendhal666 ça pourrait aider si tu donnais des types clairs à tes fonctions du top niveau, cela tend à mieux localiser l'erreur sinon l'inférence peut la propager jusqu'à ce qu'elle soit signalée plus loin de son origine réelle. Par exemple ici si tu avais mis une signature à listOfPoints, l'erreur aurait été signalée à ce niveau, réduisant d'autant la chaîne de raisonnement à mener (pour quelqu'un d'un peu expérimenté comme moi, l'erreur réelle était évidente et retrouvée en quelques instants mais tu n'as pas encore cette expérience). Évidemment ce serait plus facile si listOfPoints n'était pas une monstruosité à 9 arguments, cryptiquement nommés et absolument pas regroupés de façon significative... De même, pourquoi tes fonctions portent-elles des noms comme comptec ou comptel ? N'y a-t-il pas de nom significatif à leur donner ? Ce n'est pas comme si tu les utilisais partout et avais besoin d'une forme abrégée.
    --
    Jedaï

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    mai 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2006
    Messages : 113
    Points : 64
    Points
    64
    Par défaut
    Merci pour la réponse détaillée et claire.
    Je ne me suis pas rendu compte de l'oubli de l'argument n.
    Je reprendrais le tout sérieusement.

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

Discussions similaires

  1. No instance for (RealFrac Int)
    Par vasilpapa dans le forum Haskell
    Réponses: 0
    Dernier message: 06/06/2015, 16h08
  2. instance declaration for (Num CustomerID)
    Par Antoine_935 dans le forum Haskell
    Réponses: 2
    Dernier message: 01/07/2010, 23h57
  3. Réponses: 5
    Dernier message: 16/11/2009, 01h54
  4. [Dev c++ 4] implicite declaration of function "int kbhi
    Par Torpedox dans le forum Dev-C++
    Réponses: 5
    Dernier message: 01/01/2003, 14h37

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