+ Répondre à la discussion
Affichage des résultats 1 à 5 sur 5
  1. #1
    Membre du Club
    Inscrit en
    mai 2005
    Messages
    130
    Détails du profil
    Informations forums :
    Inscription : mai 2005
    Messages : 130
    Points : 53
    Points
    53

    Par défaut Question sur Data.fromList

    il y a qqch que je n'arrive pas à comprendre dans Data.Map :

    1.
    Code :
    1
    2
    3
    ghci > fromList [(1 ,2) ,(3 ,4) ,(3 ,2) ,(5 ,5)]
    fromList [(1,2),(3,2),(5,5)]
    it :: Map Integer Integer
    pourquoi la valeur renvoyée est-elle "fromList ..." alors que fromList, de toute évidence, n'est pas un constructeur (pour qui la majusculle initiale est obligatoire).
    cela renvoie une valeur sous la forme d'une fonction ? ? ?

    2. D'autre part ,
    Code :
    1
    2
    ghci > :t fromList
    fromList :: (Ord k) => [(k, a)] -> Map k a
    ok, jusque là ça va ...
    puis :
    Code :
    1
    2
    let myFromList = fromList
    myFromList :: [((), a)] -> Map () a
    On sent bien qu'on ne va pas aller loin avec un Map ()
    effectivement :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ghci> myFromList [(1 ,2) ,(3 ,4) ,(3 ,2) ,(5 ,5)]
    
    
    <interactive>:1:37:
        No instance for (Num ())
          arising from the literal `5' at <interactive>:1:37
        Possible fix: add an instance declaration for (Num ())
        In the expression: 5
        In the expression: (5, 5)
        In the first argument of `myFromList', namely
            `[(1, 2), (3, 4), (3, 2), (5, 5)]'
    Pourquoi ne peut-on pas créer myFromList de cette manière ?

    merci d'avance à ceux qui pourront m'expliquer ...

  2. #2
    Nouveau Membre du Club
    Profil pro
    Inscrit en
    octobre 2002
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2002
    Messages : 37
    Points : 30
    Points
    30

    Par défaut

    Citation Envoyé par james-mi Voir le message
    il y a qqch que je n'arrive pas à comprendre dans Data.Map :

    1.
    Code :
    1
    2
    3
    ghci > fromList [(1 ,2) ,(3 ,4) ,(3 ,2) ,(5 ,5)]
    fromList [(1,2),(3,2),(5,5)]
    it :: Map Integer Integer
    pourquoi la valeur renvoyée est-elle "fromList ..." alors que fromList, de toute évidence, n'est pas un constructeur (pour qui la majusculle initiale est obligatoire).
    cela renvoie une valeur sous la forme d'une fonction ? ? ?
    Ce que tu vois n'est pas la valeur renvoyée, c'est sa traduction sous forme de chaine de caractères.
    sous ghci, fromList [(1,etc...] devient l'équivalent de
    print $ fromList ...
    qui lui même est
    putStrLn $ show $ fromList ....

    Ensuite se pose la question : comment représenter une Map ? on peut imaginer plusieurs façons, mais les auteurs de Data.Map on retenu celle qui consiste a imprimer "fromList " puis la conversion de la map en liste.

    Ce qui est marrant c'est que quand tu tapes le fromList [etc...] ghci convertit la liste en Map, puis pour afficher le résultat fait aussitôt le travail inverse.

    Il n'y a pas à s'inquiéter de ca, en pratique on n'affiche pas une Map, on s'en sert pour faire des recherches.

    Citation Envoyé par james-mi Voir le message
    2. D'autre part ,
    Code :
    1
    2
    ghci > :t fromList
    fromList :: (Ord k) => [(k, a)] -> Map k a
    ok, jusque là ça va ...
    puis :
    Code :
    1
    2
    let myFromList = fromList
    myFromList :: [((), a)] -> Map () a
    On sent bien qu'on ne va pas aller loin avec un Map ()
    effectivement :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ghci> myFromList [(1 ,2) ,(3 ,4) ,(3 ,2) ,(5 ,5)]
    
    
    <interactive>:1:37:
        No instance for (Num ())
          arising from the literal `5' at <interactive>:1:37
        Possible fix: add an instance declaration for (Num ())
        In the expression: 5
        In the expression: (5, 5)
        In the first argument of `myFromList', namely
            `[(1, 2), (3, 4), (3, 2), (5, 5)]'
    Pourquoi ne peut-on pas créer myFromList de cette manière ?
    A cause de la restriction de monomorphisme, ghc(i) ne peux pas inférer un type polymorphique pour myFromList.
    En pratique dans un vrai programme, ghc dispose de suffisamment d'informations de contexte pour trouver un type précis pour une fonction du genre de myFromList, donc ca pose rarement un problème.

    Deux façons de contourner:

    1) définir myFromList comme suit :

    let myFromList l = fromList l

    2) virer la restriction de monomorphisme:

    :set -XNoMonomorphismRestriction
    let myFromList = fromList

    A propos de cette restriction, j'aurais du mal à expliquer la raison, mais elle est tellement débatue qu'une recherche de monomorphisme sur google devrait donner des réponses. En anglais , par contre.

  3. #3
    Membre du Club
    Inscrit en
    mai 2005
    Messages
    130
    Détails du profil
    Informations forums :
    Inscription : mai 2005
    Messages : 130
    Points : 53
    Points
    53

    Par défaut

    Citation Envoyé par viro Voir le message
    Ce que tu vois n'est pas la valeur renvoyée, c'est sa traduction sous forme de chaine de caractères.
    sous ghci, fromList [(1,etc...] devient l'équivalent de
    print $ fromList ...
    qui lui même est
    putStrLn $ show $ fromList ....

    Ensuite se pose la question : comment représenter une Map ? on peut imaginer plusieurs façons, mais les auteurs de Data.Map on retenu celle qui consiste a imprimer "fromList " puis la conversion de la map en liste.

    Ce qui est marrant c'est que quand tu tapes le fromList [etc...] ghci convertit la liste en Map, puis pour afficher le résultat fait aussitôt le travail inverse.

    Il n'y a pas à s'inquiéter de ca, en pratique on n'affiche pas une Map, on s'en sert pour faire des recherches.



    A cause de la restriction de monomorphisme, ghc(i) ne peux pas inférer un type polymorphique pour myFromList.
    En pratique dans un vrai programme, ghc dispose de suffisamment d'informations de contexte pour trouver un type précis pour une fonction du genre de myFromList, donc ca pose rarement un problème.

    Deux façons de contourner:

    1) définir myFromList comme suit :

    let myFromList l = fromList l

    2) virer la restriction de monomorphisme:

    :set -XNoMonomorphismRestriction
    let myFromList = fromList

    A propos de cette restriction, j'aurais du mal à expliquer la raison, mais elle est tellement débatue qu'une recherche de monomorphisme sur google devrait donner des réponses. En anglais , par contre.
    OK, merci.

    Donc quand je construit mes fonctions plus compexes, et que je les évalues dans GHCi (parce que ça aide bien quand on est un peu perdu) et que ça me renvoie "fromList [(,.....),...], je sais qu'en réalité j'ai affaire à une structure Map, c'est bien ça ?

  4. #4
    Nouveau Membre du Club
    Profil pro
    Inscrit en
    octobre 2002
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2002
    Messages : 37
    Points : 30
    Points
    30

    Par défaut

    Citation Envoyé par james-mi Voir le message
    OK, merci.

    Donc quand je construit mes fonctions plus compexes, et que je les évalues dans GHCi (parce que ça aide bien quand on est un peu perdu) et que ça me renvoie "fromList [(,.....),...], je sais qu'en réalité j'ai affaire à une structure Map, c'est bien ça ?
    Pas forcément. Rien n'empêche qu'un autre type de donnée définisse sa méthode show par "fromList [... ]"
    Après tout, ce n'est que du texte.
    Donc pour en être sûr, il te faut interroger le type de ton expression; en tapant sous ghci :t mon_expression_complexe.

    P.S, précision supplémentaire au sujet du problème:

    Code :
    1
    2
    let myFromList = fromList
    -- myFromList :: [((), a)] -> Map () a
    quand tu le compile, ghc te refuse avec le message suivant
    Code :
    1
    2
    3
    4
    5
    6
        Ambiguous type variable `k' in the constraint:
          `Ord k' arising from a use of `fromList' at tt.hs:6:13-20
        Possible cause: the monomorphism restriction applied to the following:
          myFromList :: forall a. [(k, a)] -> Map k a (bound at tt.hs:6:0)
        Probable fix: give these definition(s) an explicit type signature
                      or use -XNoMonomorphismRestriction
    Or, il te l'a accepté sous ghci, mais avec une signature bizarre. Ce qui se passe, c'est que sous ghci, il y a des règles qui font qu'un type par défaut est sélectionné quand il y a ambiguité. Dans ce cas, le type par défaut est () donc Map k a devient Map () a.

    Ce sont ces règles de "type par défaut" qui sont responsables sous ghci du résultat suivant:

    Code :
    1
    2
    3
    4
    5
    6
    Prelude> :t (+)
    (+) :: (Num a) => a -> a -> a
    Prelude> let p=(+)
    Prelude> :t p
    p :: Integer -> Integer -> Integer
    Prelude>
    Donc Integer est le type par défaut dans ghci retenu quand il y a contrainte sur la classe Num.


    Code :
    1
    2
    3
    4
    5
    6
    7
    Prelude> import Data.List
    Prelude Data.List> :t sort
    sort :: (Ord a) => [a] -> [a]
    Prelude Data.List> let s=sort
    Prelude Data.List> :t s
    s :: [()] -> [()]
    Prelude Data.List>
    Donc () est le type par défaut retenu dans ghci quand il y a contrainte sur la classe Ord.

    Code :
    1
    2
    3
    4
    5
    6
    7
    Prelude Data.List> :t show
    show :: (Show a) => a -> String
    Prelude Data.List>                                                                                                                                                    
    Prelude Data.List> let h=show                                                                                                                                         
    Prelude Data.List> :t h                                                                                                                                               
    h :: () -> String                                                                                                                                                     
    Prelude Data.List>
    Donc () est le type par défaut retenu dans ghci quand il y a contrainte sur la classe Show.

    etc, etc, etc.

  5. #5
    Membre du Club
    Inscrit en
    mai 2005
    Messages
    130
    Détails du profil
    Informations forums :
    Inscription : mai 2005
    Messages : 130
    Points : 53
    Points
    53

    Par défaut

    Citation Envoyé par viro Voir le message
    ...
    OK merci viro, ça m'éclaircit bien les idées

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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •