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 :

Problème de signature


Sujet :

Haskell

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

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

    Informations forums :
    Inscription : Septembre 2012
    Messages : 6
    Points : 7
    Points
    7
    Par défaut Problème de signature
    Je débute. Et je bute sur un problème régulièrement. Impossible d'écrire une signature de fonction acceptée par GHCi.
    Par exemple, la dernière fonction que j'ai écrite pour simplement résoudre une équation quadratique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    quadratic a b c
     | delta < 0  = []
     | delta == 0 = [sol]
     | sol1<sol2  = [sol1, sol2]
     | otherwise  = [sol2, sol1] 
       where delta = b ^ 2 - 4.0 * a * c
             sol = (-b) / (2.0*a)
             sol1 = ((-b)+(sqrt delta))/(2.0*a)
             sol2 = ((-b)-(sqrt delta))/(2.0*a)
    Ca fonctionne. Alors j'essaie de la faire précéder de sa signature. Celle qui me parraît logique serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     quadratic :: (Num a) => a -> a -> a -> [a]
    Mais non, GHCi se perd dans les inférences de type.
    Pas mieux avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     quadratic :: (Floating a) => a -> a -> a -> [a]
    Ni même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     quadratic :: a -> a -> a -> [a]
    Alors je vais interroger GHCi en tapant :t quadratic et je vois que la signature est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    quadratic :: (Ord a, Floating a) => a -> a -> a -> [a]
    Soit mais alors qu'on dit qu'Haskell est concis, quelque chose m'échappe grandement. Je pensais que par la hiérarchie des types, il n'y avait pas à 'fouiller' dans les expressions ce qui relève de Ord, Floating, etc.

    Alors pourquoi fondamentalement je galère autant avec cet aspect basique qui est très décourageant avec tout ce que ce langage promet d'inférence. Je ne comprends toujours pas pourquoi il a fallu préciser le type le plus général de 'a' (Ord) et son plus restreint (Floating).

    Merci de vos lumières.

  2. #2
    Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    65
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Janvier 2007
    Messages : 65
    Points : 54
    Points
    54
    Par défaut
    Salut gg373,
    Ord et Floating ne sont pas en connection hiérarchique, voit le diagramme sur:
    http://blogs.msdn.com/b/saeed/archiv...y-diagram.aspx

    Nom : original.png
Affichages : 270
Taille : 24,1 Ko

    Tu utilises le signe (<) dont la signature est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (<) :: Ord a => a -> a -> Bool
    et la fonction sqrt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sqrt :: Floating a => a -> a
    Donc forcément ta fonction doit spécifier elle aussi ces deux contraintes, sinon un utilisateur de ta fonction pourrait passer un paramètre inadéquat, comme une String.

    Mais tu peux spécifier des contraintes plus restrictives: par example RealFloat "descend" à la fois de Ord et Floating:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    quadratic :: (RealFloat a) => a -> a -> a -> [a]
    fonctionne. Mais c'est généralement une meilleur idée de laisser le type le plus générique.

  3. #3
    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
    Bonjour,

    La signature inférée par GHC est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    quadratic :: (Ord a, Floating a) => a -> a -> a -> [a]
    C'est le cas parce que :
    - tu utilises un opérateur de comparaison sur une valeur du type a ;
    - tu utilises l'opérateur de division sur une valeur de type a.

    Le problème, c'est que lorsque tu écris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    quadratic :: (Num a) => a -> a -> a -> [a]
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    quadratic :: (Floating a) => a -> a -> a -> [a]
    Aucune de ces deux signatures ne garantit qu'il existe un ordre sur a.

    ---

    Par la suite, je ne comprends pas vraiment ce qui t'importune.
    Le fait qu'il n'y ait pas un nom pour "un type qui est à la fois Floating et Ord" ?
    Cela me semble plutôt raisonnable, puisque donner un nom à chaque combinaison serait exponentiel (et les noms deviendraient définitivement ridicules).

    Le fait qu'il soit dur d'écrire une signature de type par soi-même ? C'est justement pour ça que l'inférence de type est appréciable, tu demandes simplement à GHC d'inférer pour toi le type le plus général. Comme tu l'as fait. La plupart des éditeurs te permettent même d'écrire cette signature inférée pour toi au bon endroit.

    Mais sinon, oui c'est assez ennuyant de deviner soi-même un type général pour un terme.

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

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

    Informations forums :
    Inscription : Septembre 2012
    Messages : 6
    Points : 7
    Points
    7
    Par défaut
    Bonjour !

    Merci de vos réponses lumineuses. Je débute avec l'excellent ouvrage de Miran Lipovaca. Je me demande s'il y a mieux dans ce cas...

    @Ptival : oui mon message est un peu confus car c'est en le rédigeant que j'ai réalisé que je pouvais demander la signature à GHCi. Et finalement, c'est une excellente pratique. Et puis aussi j'avais tout simplement mal assimilé la hiérarchie des types et classes. J'ai honte.

    @kaukau : okey, j'avais jeté une oeil (trop) rapide à cette hiérarchie et il me semblait si intuitif que Num dérive (c'est le mot correct dans le monde Haskell ?) de Ord. Ce n'est pas le cas. Est-ce pour permettre l'implémentation de nombres non ordonnables comme les nombres complexes que l'on n'a pas cet héritage ?

    Cordialement.

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/01/2008, 18h34
  2. problème de signature de mes constructeurs
    Par Kuroro dans le forum Langage
    Réponses: 11
    Dernier message: 16/05/2007, 15h47
  3. Problème de signature d'une assembly
    Par lapec_and_cie dans le forum Delphi .NET
    Réponses: 5
    Dernier message: 23/01/2006, 12h31

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