Bonjour à tous
Aujourd'hui je faisais un petit peu de Haskell, histoire de découvrir quelque chose de nouveau, et je me frottais un peu aux histoires d'évaluation explicite avec les listes.
Histoire de commencer petit, je voulais faire une petite fonction qui ne me sorte pas de out of memory pour faire une somme toute bête.
Donc dans mon interpréteur GhCI (Haskell Platform) je fais:
import list.Data
let sum' liste = foldl' (+) 0 liste
:t sum'
sum' :: Num b => [b] -> b
Jusque là tout va bien. Ça marche avec des listes d'entiers, de réels, etc… comme prévu.
Après, je me dis "tiens on va condenser un peu"
let sum' = foldl' (+) 0
:t sum'
sum' :: [Integer] -> Integer
Gni ??? Bon, on teste avec l'expression sans let…
:t foldl' (+) 0
foldl' (+) 0 :: Num b => [b] -> b
Re-gni ??? Bon, et avec un lambda ?
let sum' = \x -> foldl' (+) 0 x
:t sum'
sum' :: [Integer] -> Integer
Comprends plus… Quelqu'un pourrait-il me dire pourquoi à un moment donné je perds la généricité ?
En général je donne le moins d'information possible sur le type, donc je ne comprends pas d'où vient cette spécialisation soudaine…
# Seulement dans l'interpréteur ghci
Posté par anaseto . Évalué à 1. Dernière modification le 30 juillet 2014 à 12:31.
Je pense que ghc et ghci essaient de spécialiser sous certaines conditions à un type le plus petit possible (sans doute pour des raisons de performances). Si tu écris
let sum' = foldl' (+) 0
dans un fichier, dans lequel tu utilises ensuite cette fonction avec une liste de flottants, et que tu compiles avec ghc, tu n'auras pas les problèmes de ghci, car ghc voit d'avance tout le fichier avant de décider la spécialisation (dans ghci je suppose que tu n'as pas d'autre choix que de spécifier à la main la signature).[^] # Re: Seulement dans l'interpréteur ghci
Posté par PyroTokyo . Évalué à 1.
Je viens de faire un test sous Arch, avec ghc 7.8.3, et il semblerait que cette spécialisation n'ait pas lieu. Les 2 écritures restent équivalentes.
Donc c'est peut-être dû à ghc 7.6.2 ?
[^] # Re: Seulement dans l'interpréteur ghci
Posté par anaseto . Évalué à 2.
J'ai trouvé : c'est le «monomorphism restriction» qui est responsable, et il a été désactivé par défaut dans ghci dans la 7.8.1. Tu peux aussi le désactiver manuellement dans ghci avec
:set -XNoMonomorphismRestriction
.[^] # Re: Seulement dans l'interpréteur ghci
Posté par PyroTokyo . Évalué à 1.
OK, j'y vois un peu plus clair effectivement…
Il faut donc spécifier une signature quand cette restriction est active…
Mais dans ce cas, pour ceci ne marche pas ?
Il faut absolument passer par le style déclaratif plutôt que par une expression ?
[^] # Re: Seulement dans l'interpréteur ghci
Posté par anaseto . Évalué à 1. Dernière modification le 30 juillet 2014 à 19:35.
Je ne suis pas du tout un spécialiste du système de types de haskell (ni de haskell tout court), donc je ne suis pas sûr, mais on dirait. En tous cas c'est une « feature » assez obscure de haskell. Ceci dit, c'est un problème qui, en dehors de ghci, a très peu de chances d'intervenir dans un vrai programme. Et même dans une expression, si tu écris
let sum' = foldl (+) 0 in sum' [1.2,1.5]
dans ghc (ou ghci) ne va pas spécialiser la fonction plus que nécessaire vu qu'il sait déjà que tu vas l'appliquer à une liste de flottants avant.[^] # Re: Seulement dans l'interpréteur ghci
Posté par Zylabon . Évalué à 2. Dernière modification le 30 juillet 2014 à 22:30.
Ça ne marche pas parce que la restriction monomorphique est sur le paramètre de sum', pas celui de
foldl' (+) 0
Dans cette page : http://www.haskell.org/haskellwiki/Monomorphism_restriction
Tu te trouve dans le cas :
show
est polymorphe, mais la restriction est sur le paramètre def4
Tu dois typer sum'
La restriction monomorphique est vraiment moche…
Please do not feed the trolls
[^] # Re: Seulement dans l'interpréteur ghci
Posté par Zylabon . Évalué à 2.
haaa trop tard pour éditer, je voulais préciser la syntaxe pour GHCI :
Please do not feed the trolls
[^] # Re: Seulement dans l'interpréteur ghci
Posté par PyroTokyo . Évalué à 1.
Merci pour la réponse, c'est effectivement plus clair.
Une chose en amenant une autre, j'ai commencé à lire plus en détail sur ce "monomorphism reduction", et je suis tombé sur d'autres choses que je ne trouve même pas mentionnées dans les livres du genre "Real World Haskell", à savoir scoped types, pattern type definition, etc… Ce dernier me laisse particulièrement perplexe aussi: il est dit que c'est complètement orthogonal au type definition que j'utilise d'habitude, mais j'ai beaucoup de mal à voir la valeur ajoutée. Quoi qu'il en soit, c'est un peu la jungle dans toutes ces extensions GHC !
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.