Précédent   Forum du club des développeurs et IT Pro > Autres langages > Langages fonctionnels > Haskell
Haskell Forum d'entraide sur la programmation en langage fonctionnel Haskell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 14/09/2012, 10h47   #1
gg373
Invité de passage
 
Homme Gérard Gauthier
Développeur informatique
Inscription : septembre 2012
Messages : 6
Détails du profil
Informations personnelles :
Nom : Homme Gérard Gauthier
Localisation : France, Indre et Loire (Centre)

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

Informations forums :
Inscription : septembre 2012
Messages : 6
Points : 4
Points : 4
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 :
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 :
 quadratic :: (Num a) => a -> a -> a -> [a]
Mais non, GHCi se perd dans les inférences de type.
Pas mieux avec :
Code :
 quadratic :: (Floating a) => a -> a -> a -> [a]
Ni même :
Code :
 quadratic :: a -> a -> a -> [a]
Alors je vais interroger GHCi en tapant :t quadratic et je vois que la signature est:
Code :
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.
gg373 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2012, 02h11   #2
kaukau
Membre du Club
 
Inscription : janvier 2007
Messages : 64
Détails du profil
Informations personnelles :
Âge : 34

Informations forums :
Inscription : janvier 2007
Messages : 64
Points : 40
Points : 40
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

Tu utilises le signe (<) dont la signature est:
Code :
(<) :: Ord a => a -> a -> Bool
et la fonction sqrt:
Code :
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 :
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.
kaukau est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2012, 02h13   #3
Ptival
Membre actif
 
Avatar de Ptival
 
Homme Valentin Robert
Étudiant
Inscription : juin 2004
Messages : 70
Détails du profil
Informations personnelles :
Nom : Homme Valentin Robert
Âge : 24
Localisation : Etats-Unis

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : juin 2004
Messages : 70
Points : 172
Points : 172
Bonjour,

La signature inférée par GHC est :

Code :
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 :
quadratic :: (Num a) => a -> a -> a -> [a]
ou

Code :
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.
Ptival est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2012, 09h35   #4
gg373
Invité de passage
 
Homme Gérard Gauthier
Développeur informatique
Inscription : septembre 2012
Messages : 6
Détails du profil
Informations personnelles :
Nom : Homme Gérard Gauthier
Localisation : France, Indre et Loire (Centre)

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

Informations forums :
Inscription : septembre 2012
Messages : 6
Points : 4
Points : 4
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.
gg373 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 07h34.


 
 
 
 
Partenaires

Hébergement Web