IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

A Gentle Introduction to Haskell, version 98


précédentsommairesuivant

XII. Pièges du typage

Cette courte partie devrait vous donner une bonne intuition en ce qui concerne les problèmes que le système de type de Haskell pose aux débutants.

XII-A. Let-Bound Polymorphism

Tout langage utilisant le système de type de Hindley-Milner possède ce que l'on appelle let-bound polymorphism, parce que les identifiants non bornés par une clause let ou where, et non situés au niveau principal d'un module, sont limités par leur propre polymorphisme. En particulier, une fonction lambda-bound, c'est-à-dire qui est passée en argument à une autre fonction, ne peut pas être instanciée de deux manières différentes. Par exemple, le programme suivant est invalide :

 
Sélectionnez
let f g  =  (g [], g 'a')                       – ill-typed expression
in f (\x->x)

En effet, le représentant d'une fonction abstraite, dont le type principal est a->a, est utilisée dans f de deux manières différentes : la première fois avec le type [a]->[a] ; et la seconde avec le type Char->Char.

XII-B. Surcharge numérique

Il est facile d'oublier que, parfois, les valeurs numériques sont surchargées, et pas implicitement converties dans les divers types numériques comme dans beaucoup d'autres langages. Ainsi des expressions numériques très générales ne peuvent parfois pas être généralisées. On rencontre souvent une erreur de typage pour des valeurs numériques comme celle-ci :

 
Sélectionnez
xs moyens = xs de somme/xs de longueur           – Mal !

/ exige des arguments de type fraction, mais le résultat de length est de type Int. Cette erreur de type doit être corrigée en rendant le transtypage explicite :

 
Sélectionnez
average                 :: (Fractional a) => [a] -> a
average xs              =  sum xs / fromIntegral (length xs)

XII-C. Les Restrictions monomorphiques

Le système de types de Haskell contient une restriction liée aux classes de type qui n'est pas présente dans le système de types standard de Hindley-Milner : la restriction de monomorphisme. La raison de cette restriction provient d'une subtile ambiguïté de types et est entièrement expliquée dans ce rapport. Pour faire court, on peut le résumer comme :

La restriction de monomorphisme indique que n'importe quel identifiant borné par un binding (cela inclut les bindings sur les identifiants seuls), et n'ayant aucun type explicite dans sa signature, doit être monomorphe. Un identifiant est monomorphe s'il n'est pas surchargé, ou bien s'il est surchargé, mais est employé de manière à n'obtenir au plus qu'une seule surcharge et n'est pas exporté.

Les violations de cette restriction ont comme conséquence une erreur de typage statique. La manière la plus simple d'éviter ce problème est de fournir un type explicite dans la signature. On peut remarquer que n'importe quel type mis en signature suffira, du moment qu'il s'agit d'un type correct.

Une violation courante de cette restriction survient lorsqu'on définit des fonctions d'ordre supérieur. En voici un exemple avec la définition classique de la somme :

 
Sélectionnez
sum                     =  foldl (+) 0

On peut corriger cette erreur de typage statique, en ajoutant un type dans la signature, comme suit :

 
Sélectionnez
sum                     :: (Num a) => [a] -> a

On remarque ainsi que le problème ne serait pas survenu si nous avions écrit ceci :

 
Sélectionnez
sum xs                  =  foldl (+) 0 xs

En effet, la restriction n'est appliquée que dans les binding.


précédentsommairesuivant

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2013 gorgonite. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.