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 :

simplifier mon where


Sujet :

Haskell

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    226
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 226
    Points : 72
    Points
    72
    Par défaut simplifier mon where
    bonjour j'ai le code suivant :

    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
     
    -- Evaluation des expressions
    evalExp :: EXP -> MEMORY -> TREE
    evalExp (CONST x) memory = x
    evalExp (ID x) memory = getMemory x memory
    evalExp (ADD x y) memory = if letype(xEval)==(Just IntType) && letype(yEval)==(Just IntType) 
                               then TREEVALUE (INT ((getINT xEval) + (getINT yEval)))
                               else TREEVALUE (Error)
            where
                xEval = evalExp x memory
                yEval = evalExp y memory
     
    evalExp (SUB x y) memory = if letype(xEval)==(Just IntType) && letype(yEval)==(Just IntType) 
                               then TREEVALUE (INT ((getINT xEval) - (getINT yEval)))
                               else TREEVALUE (Error)
            where
                xEval = evalExp x memory
                yEval = evalExp y memory
     
    evalExp (MULTI x y) memory = if letype(xEval)==(Just IntType) && letype(yEval)==(Just IntType) 
                                 then TREEVALUE (INT ((getINT xEval) * (getINT yEval)))
                                 else TREEVALUE (Error)
            where
                xEval = evalExp x memory
                yEval = evalExp y memory
     
    evalExp (COMP x y) memory = if letype(xEval)==(Just IntType) && letype(yEval)==(Just IntType) 
                                then TREEVALUE (BOOL ((getINT xEval) < (getINT yEval)))
                                else TREEVALUE (Error)
            where
                xEval = evalExp x memory
                yEval = evalExp y memory
     
    evalExp (NEG x) memory = if letype(xEval)==(Just BoolType) 
                             then TREEVALUE (BOOL (not (getBOOL xEval)))
                             else TREEVALUE(Error)
            where 
                xEval = evalExp x memory
     
    evalExp (AND x y) memory = if letype(xEval)==(Just BoolType) && letype(yEval)==(Just BoolType) 
                                 then TREEVALUE (BOOL ((getBOOL xEval) && (getBOOL yEval)))
                                 else TREEVALUE(Error)
            where
                xEval = evalExp x memory
                yEval = evalExp y memory
     
    evalExp (OR x y) memory = if letype(xEval)==(Just BoolType) && letype(yEval)==(Just BoolType) 
                                then TREEVALUE (BOOL ((getBOOL xEval) || (getBOOL yEval)))
                                else TREEVALUE(Error)
            where
                xEval = evalExp x memory
                yEval = evalExp y memory
    ma question serais comment je pourais remplacer le where ou le simplifier pour eviter de le repeter aussi souvent merci

  2. #2
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    Ce n’est pas tant le contenu de ton « where » qu’il faut factoriser que le mécanisme complet de vérification et d’évaluation des opérandes. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    evalExp (NEG ex) memory = deepEval memory [ex] [BoolType] $
            \[x] -> BOOL (not (getBOOL x))
     
    evalExp (OR ex ey) memory = deepEval memory [ex, ey] [BoolType, BoolType] $
            \[x, y] -> BOOL (getBOOL x || getBOOL y)
     
    deepEval :: MEMORY -> [EXP] -> [TYPE] -> ([TREE] -> TREE) -> EXP
    deepEval memory operands expectedTypes operator =
            let
                    operandValues = map (flip evalExp memory) operands
                    actualTypes = map letype operandValues
            in if actualTypes == expectedTypes
                    then TREEVALUE (operator operandValues)
                    else TREEVALUE Error
    En remplaçant TREEVALUE (c’est moche d’écrire tout en majuscule, TreeValue serait plus lisible) par un Maybe qui jouerait le même rôle, il serait possible d’améliorer encore tout ça.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    226
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 226
    Points : 72
    Points
    72
    Par défaut
    avec ton code j'ai le message d'erreur suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     Couldn't match expected type `EXP' with actual type `TREE'
        In the return type of a call of `TREEVALUE'
        In the expression: TREEVALUE (operator operandValues)
        In the expression:
          if actualTypes == expectedTypes then
              TREEVALUE (operator operandValues)
          else
              TREEVALUE Error
    pour la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     deepEval :: MEMORY -> [EXP] -> [TYPE] -> ([TREE] -> TREE) -> EXP
     deepEval memory operands expectedTypes operator =
            let
                    operandValues = map (flip evalExp memory) operands
                    actualTypes = map getType operandValues
            in if actualTypes == expectedTypes
                    then TREEVALUE (operator operandValues)
                    else TREEVALUE Error

  4. #4
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    deepEval :: MEMORY -> [EXP] -> [TYPE] -> ([TREE] -> TREE) -> EXP TREE

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    226
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 226
    Points : 72
    Points
    72
    Par défaut
    toujours un problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     Illegal type signature: `MEMORY
                                 -> [EXP]
                                    -> [TYPE]
                                       -> ([TREE] -> TREE)
                                          -> TREE deepEval memory operands expectedTypes operator'
          Perhaps you intended to use -XScopedTypeVariables
        In a pattern type-signature
    pourtant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
          type MEMORY = [(IDs,TREE)]

  6. #6
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    deepEval :: MEMORY -> [EXP] -> [TYPE] -> ([TREE] -> TREE) -> EXP TREE deepEval memory operands expectedTypes operator

    Tu positionnes ton curseur au niveau du smiley et tu appuis sur la touche Entrée (c’est la touche un peu plus grande que les autres avec « Entrée » marquée dessus).

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    226
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 226
    Points : 72
    Points
    72
    Par défaut
    ton Entrée est bien fait le message d'erreur est toujours la
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    deepEval :: MEMORY -> [EXP] -> [TYPE] -> ([TREE] -> TREE) -> EXP
     
    deepEval memory operands expectedTypes operator =
            let
                    operandValues = map (flip evalExp memory) operands
                    actualTypes = map getType operandValues
            in if actualTypes == expectedTypes
                    then TREEVALUE (operator operandValues)
                    else TREEVALUE Error
    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
    91
    92
    93
     
    [1 of 1] Compiling Main             ( /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs, interpreted )
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:110:13:
        Illegal type signature: `MEMORY
                                 -> [EXP]
                                    -> [TYPE]
                                       -> ([TREE] -> TREE)
                                          -> EXP deepEval memory operands expectedTypes operator'
          Perhaps you intended to use -XScopedTypeVariables
        In a pattern type-signature
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:116:51:
        Not in scope: `memory'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:116:59:
        Not in scope: `operands'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:118:30:
        Not in scope: `expectedTypes'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:119:33:
        Not in scope: `operator'
    Failed, modules loaded: none.
    Prelude> [1 of 1] Compiling Main             ( /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs, interpreted )
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:110:13:
        Illegal type signature: `MEMORY
                                 -> [EXP]
                                    -> [TYPE]
                                       -> ([TREE] -> TREE)
                                          -> EXP deepEval memory operands expectedTypes operator'
          Perhaps you intended to use -XScopedTypeVariables
        In a pattern type-signature
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:116:51:
        Not in scope: `memory'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:116:59:
        Not in scope: `operands'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:118:30:
        Not in scope: `expectedTypes'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:119:33:
        Not in scope: `operator'
    Failed, modules loaded: none.
    Prelude> [1 of 1] Compiling Main             ( /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs, interpreted )
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:110:13:
        Illegal type signature: `MEMORY
                                 -> [EXP]
                                    -> [TYPE]
                                       -> ([TREE] -> TREE)
                                          -> EXP deepEval memory operands expectedTypes operator deepEval memory operands expectedTypes operator'
          Perhaps you intended to use -XScopedTypeVariables
        In a pattern type-signature
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:114:51:
        Not in scope: `memory'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:114:59:
        Not in scope: `operands'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:116:30:
        Not in scope: `expectedTypes'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:117:33:
        Not in scope: `operator'
    Failed, modules loaded: none.
    Prelude> [1 of 1] Compiling Main             ( /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs, interpreted )
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:110:13:
        Illegal type signature: `MEMORY
                                 -> [EXP]
                                    -> [TYPE]
                                       -> ([TREE] -> TREE)
                                          -> EXP deepEval memory operands expectedTypes operator deepEval memory operands expectedTypes operator'
          Perhaps you intended to use -XScopedTypeVariables
        In a pattern type-signature
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:114:51:
        Not in scope: `memory'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:114:59:
        Not in scope: `operands'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:116:30:
        Not in scope: `expectedTypes'
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:117:33:
        Not in scope: `operator'
    Failed, modules load

  8. #8
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 97
    Points : 307
    Points
    307
    Par défaut
    @mimi6060

    Tu pourrais donner la définition de tes données algébriques EXP et TREE car il
    y a vraiment moyen de se faire plaisir avec Haskell sur ce genre de problème

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    226
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 226
    Points : 72
    Points
    72
    Par défaut
    voila :
    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
     
    data EXP = ID IDs
              | CONST TREE
              | ADD   EXP EXP
              | SUB   EXP EXP
              | MULTI EXP EXP
              | COMP  EXP EXP
              | NEG   EXP
              | AND   EXP EXP
              | OR    EXP EXP
              | EQUAL EXP EXP
              | PAIR  EXP EXP
              | FST   EXP
              | SND   EXP
              | IF    EXP EXP EXP
              deriving(Show, Eq)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    data VALUE = INT Int
               | BOOL Bool
               | Error
               deriving(Show, Eq, Ord)
     
    data TREE = PAIRTREE TREE TREE
              | TREEVALUE  VALUE
              | NIL
              deriving(Show, Eq)

  10. #10
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    Citation Envoyé par mimi6060 Voir le message
    ton Entrée est bien fait le message d'erreur est toujours la
    Voici la version corrigée en fonction de la définition des ADT que tu as fournis. Ça ne change cependant rien au fait qu’il te manque un retour à la ligne dans ton code source. Le message d’erreur est explicite (si ça peut te convaincre, ça compile chez moi).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    deepEval :: MEMORY -> [EXP] -> [TYPE] -> ([TREE] -> VALUE) -> TREE
    deepEval memory operands expectedTypes operator =
            let
                    operandValues = map (flip evalExp memory) operands
                    actualTypes = map (fromJust . letype) operandValues
            in if actualTypes == expectedTypes
                    then TREEVALUE (operator operandValues)
                    else TREEVALUE Error

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    226
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 226
    Points : 72
    Points
    72
    Par défaut
    j'ai le message d'erreur suivant maintenant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:113:47:
        Couldn't match type `TYPE' with `Maybe b0'
        Expected type: TREE -> Maybe b0
          Actual type: TREE -> TYPE
        In the second argument of `(.)', namely `getType'
        In the first argument of `map', namely `(fromJust . getType)'
        In the expression: map (fromJust . getType) operandValues
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    -- Retourne le type d'une pair d'un arbre
    getType :: TREE -> TYPE
    getType (TREEVALUE (INT x)) = IntType
    getType (TREEVALUE (BOOL x)) = BoolType
    getType (PAIRTREE x y ) = TreeType
    getType x = ErrorType

  12. #12
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    Remplace (fromJust . letype) par getType dans ce cas.

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    226
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 226
    Points : 72
    Points
    72
    Par défaut
    merci ca fonctionne enfin

  14. #14
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 97
    Points : 307
    Points
    307
    Par défaut
    Ma version (compilée avec GHC 7.6.3) est plus 'avancée' je pense mais permet de mettre en avant ce qu'Haskell a à offrir

    Bien entendu, les critiques sont les bienvenues

    Code Haskell : 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
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
     
    import Control.Monad (ap)
    import Control.Applicative (Applicative(..), (<$>))
     
    -- Représenter la récursion au niveau du typage
    newtype Mu f = Mu { unMu :: f (Mu f) }
     
    -- Utiliser un fonction d'ordre supérieur pour parcourir une structure récursive
    foldMu :: Functor f => (f a -> a) -> Mu f -> a
    foldMu f = f . fmap (foldMu f) . unMu
     
    -- Nos structures récursives
    type Ids = String
    type Exp = Mu Exp1
     
    data Exp1 a = Id Ids
                | Const Tree
                | Add a a
                | Sub a a
                | Multi a a
                | Comp a a
                | Neg a
                | And a a
                | Or a a
                | Equal a a
                | Pair a a
                | Fst a
                | Snd a
                | If a a a
     
    type Tree = Mu Tree1
     
    data Tree1 a = PairTree a a
                 | TreeValue Value deriving Show
     
    data Value = Number Int
               | Boolean Bool deriving Show
     
    type Memory = [(Ids, Tree)]
     
    -- Accès au point de récursion de chaque structure récursive
    instance Functor Exp1 where
        fmap _ (Id i)      = Id i
        fmap _ (Const t)   = Const t
        fmap f (Add x y)   = Add (f x) (f y)
        fmap f (Sub x y)   = Sub (f x) (f y)
        fmap f (Multi x y) = Multi (f x) (f y)
        fmap f (Comp x y)  = Comp (f x) (f y)
        fmap f (Neg x)     = Neg (f x)
        fmap f (And x y)   = And (f x) (f y)
        fmap f (Or x y)    = Or (f x) (f y)
        fmap f (Equal x y) = Equal (f x) (f y)
        fmap f (Pair x y)  = Pair (f x) (f y)
        fmap f (Fst x)     = Fst (f x)
        fmap f (Snd x)     = Snd (f x)
        fmap f (If x y z)  = If (f x) (f y) (f z)
     
    instance Functor Tree1 where
        fmap f (PairTree x y) =  PairTree (f x) (f y)
        fmap _ (TreeValue v)  = TreeValue v
     
    -- Exp Api
    newId :: Ids -> Exp
    newId = Mu . Id
     
    constExp :: Tree -> Exp
    constExp = Mu . Const
     
    add :: Exp -> Exp -> Exp
    add x y = Mu $ Add x y
     
    sub :: Exp -> Exp -> Exp
    sub x y = Mu $ Sub x y
     
    multi :: Exp -> Exp -> Exp
    multi x y = Mu $ Multi x y
     
    comp :: Exp -> Exp -> Exp
    comp x y = Mu $ Comp x y
     
    neg :: Exp -> Exp
    neg = Mu . Neg
     
    and :: Exp -> Exp -> Exp
    and x y = Mu $ And x y
     
    or :: Exp -> Exp -> Exp
    or x y = Mu $ Or x y
     
    equal :: Exp -> Exp -> Exp
    equal x y = Mu $ Equal x y
     
    pair :: Exp -> Exp -> Exp
    pair x y = Mu $ Pair x y
     
    -- Conflit possible si Control.Arrow est importé
    first :: Exp -> Exp
    first = Mu . Fst
     
    -- Conflit possible si Control.Arrow est importé
    second :: Exp -> Exp
    second = Mu . Snd
     
    ifExp :: Exp -> Exp -> Exp -> Exp
    ifExp x y z = Mu $ If x y z
     
    -- Tree Api
    pairTree :: Tree -> Tree -> Tree
    pairTree x y = Mu $ PairTree x y
     
    treeValue :: Value -> Tree
    treeValue = Mu . TreeValue
     
    toNumber :: Int -> Tree
    toNumber = treeValue . Number
     
    toBoolean :: Bool -> Tree
    toBoolean = treeValue . Boolean
     
    -- eval Api
    newtype Eval a = Eval { runEval :: Memory -> Maybe a } -- équivalent de ReaderT Memory Maybe a
     
    instance Functor Eval where
        fmap f (Eval k) = Eval (fmap f . k)
     
    instance Applicative Eval where
        pure = return
     
        (<*>) = ap
     
    instance Monad Eval where
        return = Eval . const . Just
     
        (Eval k) >>= f =
            Eval $ \mem -> do
                a <- k mem
                runEval (f a) mem
     
    askMemory :: Eval Memory
    askMemory = Eval Just
     
    evalError :: Eval a
    evalError = Eval $ const Nothing
     
    evalInt :: Tree -> Eval Int
    evalInt = foldMu go
      where
        go (TreeValue v) =
            case v of
                Number i -> return i
                _        -> evalError
        go _ = evalError
     
    evalBool :: Tree -> Eval Bool
    evalBool = foldMu go
      where
        go (TreeValue v) =
            case v of
                Boolean b -> return b
                _         -> evalError
        go _ = evalError
     
    evalPair :: Tree -> Eval (Tree, Tree)
    evalPair tree = do
        res <- foldMu go tree $ 0
        case res of
            (1, Mu(PairTree x y)) -> return (x, y)
            _                     -> evalError
      where
        go (PairTree kx ky) level = do
            let level2 = level+1
            (_,x) <- kx level2
            (_,y) <- ky level2
            let res = pairTree x y
            if level == 0
                then return (1, res) -- c'est un Pair !
                else return (level, res)
        go (TreeValue v) level = return (level, treeValue v)
     
    lookupMemory :: Ids -> Eval Tree
    lookupMemory x = do
        mem <- askMemory
        maybe evalError return (lookup x mem)
     
    evalExp :: Exp -> Memory -> Maybe Tree
    evalExp = runEval . foldMu go
      where
        go (Id x)    = lookupMemory x
        go (Const t) = return t
        go (Add ex ey) = do
            x <- ex >>= evalInt
            y <- ey >>= evalInt
            return $ toNumber (x + y)
        go (Sub ex ey) = do
            x <- ex >>= evalInt
            y <- ey >>= evalInt
            return $ toNumber (x - y)
        go (Multi ex ey) = do
            x <- ex >>= evalInt
            y <- ey >>= evalInt
            return $ toNumber (x * y)
        go (Comp ex ey) =  do
            x <- ex >>= evalInt
            y <- ey >>= evalInt
            return $ toBoolean (x < y)
        go (Neg ex) = do
            x <- ex >>= evalBool
            return $ toBoolean $ not x
        go (And ex ey) = do
            x <- ex >>= evalBool
            y <- ey >>= evalBool
            return $ toBoolean (x && y)
        go (Or ex ey) = do
            x <- ex >>= evalBool
            y <- ey >>= evalBool
            return $ toBoolean (x || y)
        go (Equal ex ey) = do
            x <- ex >>= evalInt
            y <- ey >>= evalInt
            return $ toBoolean (x == y)
        go (Pair ex ey) = pairTree <$> ex <*> ey
        go (Fst ex) = do
            (l,_) <- ex >>= evalPair
            return l
        go (Snd ex) = do
            (_,r) <- ex >>= evalPair
            return r
        go (If ep et ef) = do
            p <- ep >>= evalBool
            if p
                then et
                else ef

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    226
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 226
    Points : 72
    Points
    72
    Par défaut
    erreur suivante avec ton code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        The last statement in a 'do' block must be an expression
          (l, _) <- ex >>= evalPair return l
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:223:16:
        Not in scope: `l'

  16. #16
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 97
    Points : 307
    Points
    307
    Par défaut
    Citation Envoyé par mimi6060 Voir le message
    erreur suivante avec ton code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        The last statement in a 'do' block must be an expression
          (l, _) <- ex >>= evalPair return l
     
    /Users/mimimichel/Documents/workspace/projetHAskell/Setup.hs:223:16:
        Not in scope: `l'
    Je pense surtout que tu as mal indenté le code en le copiant

    concernant mon code, j'apporte une correction à evalPair qui était inefficace en introduisant paraMu:

    Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    -- Autre type de récursion (paramorphisme)
    paraMu :: Functor f => (f (Mu f, a) -> a) -> Mu f -> a
    paraMu k x@(Mu m) = k $ fmap (\m' -> (x, paraMu k m')) m

    Voici maintenant le nouveau evalPair:

    Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    evalPair :: Tree -> Eval (Tree, Tree)
    evalPair = paraMu go
      where
        go (PairTree (x, _) (y, _)) = return (x, y)
        go _                        = evalError

    Voici à nouveau le code complet:

    Code Haskell : 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
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
     
    import Control.Monad (ap)
    import Control.Applicative (Applicative(..), (<$>))
     
    -- Représenter la récursion au niveau du typage
    newtype Mu f = Mu { unMu :: f (Mu f) }
     
    -- Utiliser un fonction d'ordre supérieur pour parcourir une structure récursive (catamorphisme)
    foldMu :: Functor f => (f a -> a) -> Mu f -> a
    foldMu f = f . fmap (foldMu f) . unMu
     
    -- Autre type de récursion (paramorphisme)
    paraMu :: Functor f => (f (Mu f, a) -> a) -> Mu f -> a
    paraMu k x@(Mu m) = k $ fmap (\m' -> (x, paraMu k m')) m
     
    -- Nos structures récursives
    type Ids = String
    type Exp = Mu Exp1
     
    data Exp1 a = Id Ids
                | Const Tree
                | Add a a
                | Sub a a
                | Multi a a
                | Comp a a
                | Neg a
                | And a a
                | Or a a
                | Equal a a
                | Pair a a
                | Fst a
                | Snd a
                | If a a a
     
    type Tree = Mu Tree1
     
    data Tree1 a = PairTree a a
                 | TreeValue Value deriving Show
     
    data Value = Number Int
               | Boolean Bool deriving Show
     
    type Memory = [(Ids, Tree)]
     
    -- Accès au point de récursion de chaque structure récursive
    instance Functor Exp1 where
        fmap _ (Id i)      = Id i
        fmap _ (Const t)   = Const t
        fmap f (Add x y)   = Add (f x) (f y)
        fmap f (Sub x y)   = Sub (f x) (f y)
        fmap f (Multi x y) = Multi (f x) (f y)
        fmap f (Comp x y)  = Comp (f x) (f y)
        fmap f (Neg x)     = Neg (f x)
        fmap f (And x y)   = And (f x) (f y)
        fmap f (Or x y)    = Or (f x) (f y)
        fmap f (Equal x y) = Equal (f x) (f y)
        fmap f (Pair x y)  = Pair (f x) (f y)
        fmap f (Fst x)     = Fst (f x)
        fmap f (Snd x)     = Snd (f x)
        fmap f (If x y z)  = If (f x) (f y) (f z)
     
    instance Functor Tree1 where
        fmap f (PairTree x y) =  PairTree (f x) (f y)
        fmap _ (TreeValue v)  = TreeValue v
     
    -- Exp Api
    newId :: Ids -> Exp
    newId = Mu . Id
     
    constExp :: Tree -> Exp
    constExp = Mu . Const
     
    add :: Exp -> Exp -> Exp
    add x y = Mu $ Add x y
     
    sub :: Exp -> Exp -> Exp
    sub x y = Mu $ Sub x y
     
    multi :: Exp -> Exp -> Exp
    multi x y = Mu $ Multi x y
     
    comp :: Exp -> Exp -> Exp
    comp x y = Mu $ Comp x y
     
    neg :: Exp -> Exp
    neg = Mu . Neg
     
    and :: Exp -> Exp -> Exp
    and x y = Mu $ And x y
     
    or :: Exp -> Exp -> Exp
    or x y = Mu $ Or x y
     
    equal :: Exp -> Exp -> Exp
    equal x y = Mu $ Equal x y
     
    pair :: Exp -> Exp -> Exp
    pair x y = Mu $ Pair x y
     
    -- Conflit possible si Control.Arrow est importé
    first :: Exp -> Exp
    first = Mu . Fst
     
    -- Conflit possible si Control.Arrow est importé
    second :: Exp -> Exp
    second = Mu . Snd
     
    ifExp :: Exp -> Exp -> Exp -> Exp
    ifExp x y z = Mu $ If x y z
     
    -- Tree Api
    pairTree :: Tree -> Tree -> Tree
    pairTree x y = Mu $ PairTree x y
     
    treeValue :: Value -> Tree
    treeValue = Mu . TreeValue
     
    toNumber :: Int -> Tree
    toNumber = treeValue . Number
     
    toBoolean :: Bool -> Tree
    toBoolean = treeValue . Boolean
     
    -- eval Api
    newtype Eval a = Eval { runEval :: Memory -> Maybe a } -- équivalent de ReaderT Memory Maybe a
     
    instance Functor Eval where
        fmap f (Eval k) = Eval (fmap f . k)
     
    instance Applicative Eval where
        pure = return
     
        (<*>) = ap
     
    instance Monad Eval where
        return = Eval . const . Just
     
        Eval k >>= f =
            Eval $ \mem -> do
                a <- k mem
                runEval (f a) mem
     
    askMemory :: Eval Memory
    askMemory = Eval Just
     
    evalError :: Eval a
    evalError = Eval $ const Nothing
     
    evalInt :: Tree -> Eval Int
    evalInt = foldMu go
      where
        go (TreeValue v) =
            case v of
                Number i -> return i
                _        -> evalError
        go _ = evalError
     
    evalBool :: Tree -> Eval Bool
    evalBool = foldMu go
      where
        go (TreeValue v) =
            case v of
                Boolean b -> return b
                _         -> evalError
        go _ = evalError
     
    evalPair :: Tree -> Eval (Tree, Tree)
    evalPair = paraMu go
      where
        go (PairTree (x, _) (y, _)) = return (x, y)
        go _                        = evalError
     
    lookupMemory :: Ids -> Eval Tree
    lookupMemory x = do
        mem <- askMemory
        maybe evalError return (lookup x mem)
     
    evalExp :: Exp -> Memory -> Maybe Tree
    evalExp = runEval . foldMu go
      where
        go (Id x)    = lookupMemory x
        go (Const t) = return t
        go (Add ex ey) = do
            x <- ex >>= evalInt
            y <- ey >>= evalInt
            return $ toNumber (x + y)
        go (Sub ex ey) = do
            x <- ex >>= evalInt
            y <- ey >>= evalInt
            return $ toNumber (x - y)
        go (Multi ex ey) = do
            x <- ex >>= evalInt
            y <- ey >>= evalInt
            return $ toNumber (x * y)
        go (Comp ex ey) =  do
            x <- ex >>= evalInt
            y <- ey >>= evalInt
            return $ toBoolean (x < y)
        go (Neg ex) = do
            x <- ex >>= evalBool
            return $ toBoolean $ not x
        go (And ex ey) = do
            x <- ex >>= evalBool
            y <- ey >>= evalBool
            return $ toBoolean (x && y)
        go (Or ex ey) = do
            x <- ex >>= evalBool
            y <- ey >>= evalBool
            return $ toBoolean (x || y)
        go (Equal ex ey) = do
            x <- ex >>= evalInt
            y <- ey >>= evalInt
            return $ toBoolean (x == y)
        go (Pair ex ey) = pairTree <$> ex <*> ey
        go (Fst ex) = do
            (l,_) <- ex >>= evalPair
            return l
        go (Snd ex) = do
            (_,r) <- ex >>= evalPair
            return r
        go (If ep et ef) = do
            p <- ep >>= evalBool
            if p
                then et
                else ef

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    226
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 226
    Points : 72
    Points
    72
    Par défaut
    Ca compile merci a vous pour votre patience et vos réponses

    bonne fêtes à tous

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

Discussions similaires

  1. Simplifier mon code
    Par pierre987321 dans le forum Langage
    Réponses: 5
    Dernier message: 07/04/2010, 12h49
  2. Simplifier mon code "Majuscule/Minuscule"
    Par Manou34 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 24/01/2008, 17h05
  3. Réponses: 5
    Dernier message: 15/06/2007, 11h58
  4. Comment simplifier mon script ?
    Par MMO95 dans le forum Langage
    Réponses: 7
    Dernier message: 09/01/2007, 00h21
  5. sql ne comprend pas mon where!et me demande des parametres
    Par marie10 dans le forum Langage SQL
    Réponses: 10
    Dernier message: 20/04/2004, 11h08

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