software.wikisort.org - Langage_de_programmation

Search / Calendar

Haskell est un langage de programmation fonctionnel fondé sur le lambda-calcul et la logique combinatoire. Son nom vient du mathématicien et logicien Haskell Curry. Il a été créé en 1990 par un comité de chercheurs en théorie des langages intéressés par les langages fonctionnels et l'évaluation paresseuse. Le dernier standard est Haskell 2010 : c'est une version minimale et portable du langage conçue à des fins pédagogiques et pratiques, dans un souci d'interopérabilité entre les implémentations du langage et comme base de futures extensions. Le langage continue d'évoluer en 2020, principalement avec GHC, constituant ainsi un standard de facto comprenant de nombreuses extensions.

Haskell

Date de première version
Paradigmes fonctionnel
Auteur comité Haskell
Développeurs communauté Haskell
Typage Fort, statique
Dialectes Helium, O'Haskell, Template Haskell, PolyP
Influencé par Lisp et Scheme, ISWIM, FP, APL, Hope, SISAL, Miranda, ML, Lazy ML, Orwell, Alfl, Id, Ponder
Implémentations GHC, Hugs, Yhc
Système d'exploitation Multiplateforme
Site web https://www.haskell.org
Extension de fichier hs et lhs

Historique


La sortie de Miranda en 1985 provoqua un regain d'intérêt pour les langages fonctionnels à évaluation paresseuse et entraîna une explosion du nombre de tels langages expérimentaux, de sorte qu'en 1987 plus d'une douzaine d'entre eux étaient disponibles. Miranda était de loin le plus populaire mais son modèle propriétaire fermé n'encourageait pas les contributions et à la conférence FPCA '87 (Functional Programming Languages and Computer Architecture, se traduisant par langages de programmation fonctionnels et architecture des ordinateurs) à Portland en Oregon, une réunion de chercheurs éminents du domaine aboutit à la conclusion qu'il serait souhaitable d'établir un standard ouvert qui pourrait servir de base commune à de futures recherches sur les langages fonctionnels. Dans ce but ils formèrent un comité dont la tâche serait de mettre en commun les points forts des prototypes de l'époque.


Versions


Haskell 1.0 à 1.4

Le travail du comité se poursuivit de réunion en réunion et aboutit en 1990 à la définition de Haskell 1.0, suivi par diverses révisions pour les versions 1.1, 1.2, 1.3 et 1.4.

Haskell 98

Le rapport Haskell 98 établit un standard durable sur lequel toutes les implémentations subséquentes se basent. Une version révisée parait en .

Haskell 2010

Le procédé de révision du standard Haskell, nommé Haskell' (prononcé « Haskell Prime ») commença en 2006. Originellement entrepris dans l'optique de publier une nouvelle version du standard Haskell, l'effort peina à se mettre en place de façon durable et s'est maintenant fixé un objectif plus restreint : publier régulièrement (théoriquement une fois par an) une révision du rapport de 1998 intégrant quelques nouveautés introduites depuis par GHC et incontestablement acceptées et utilisées par la communauté. Haskell 2010 a ainsi ajouté une définition du mécanisme d'interface de Haskell avec d'autres langages (FFI : foreign functions interface) et supprimé les motifs « n+k » du langage (qui permettaient d'écrire : decrement (n+1) = n). Il a également officialisé un mécanisme pour spécifier quel standard on souhaite respecter dans un fichier source donné, ainsi que les extensions éventuelles, entérinant la nature plutôt modulaire du Haskell utilisée en pratique.

Versions de recherche

En 2012, Haskell est probablement le langage fonctionnel sur lequel le plus de recherches ont été entreprises. Plusieurs variantes ont été développées. Des versions parallélisées faites au Laboratory for Computer Science du Massachusetts Institute of Technology (MIT) et à l'université de Glasgow ont toutes deux été appelées Parallel Haskell. Des versions plus parallélisées et plus distribuées sont appelées Distributed Haskell (anciennement Goffin) et Eden, il existe également une tentative d'utiliser Haskell dans le cloud computing appelée Cloud Haskell. Une version d'exécution spéculative, Eager Haskell et plusieurs versions orientées objet, Haskell++, O'Haskell et Mondrian ont vu le jour. Ces diverses versions de recherche étaient assez souvent basées sur GHC et ont fréquemment laissé leurs traces dans ce compilateur lorsque l'expérimentation s'est révélée fructueuse, inspirant ainsi le support actuel pour les fils d'exécutions et les diverses formes de parallélisation du code.


Fonctionnalités


Les fonctionnalités les plus intéressantes de Haskell sont le support des fonctions récursives, l'inférence de types, les listes en compréhension, l'évaluation paresseuse et les structures de données infinies dont l'exemple phare est le type de donnée stream. Ces fonctionnalités, surtout si elles sont combinées, facilitent l'écriture et l'utilisation de fonctions et la manipulation des données. Le système de types, objet de nombreuses recherches, est également l'un des plus expressifs et l'un des plus aptes à mettre en œuvre, de façon statique, de nombreuses contraintes ordinairement vérifiées à l'exécution. Haskell se distingue également par l'utilisation de monades pour les entrées/sorties et pour la gestion des exceptions, rendue nécessaire par l'une des plus importantes spécificités du langage, à savoir que Haskell est un langage fonctionnel pur, ce qui signifie que, de façon inhérente, aucun effet de bord n'est autorisé, ni les entrées/sorties, ni les affectations de variables, ni les exceptions. La plupart des langages fonctionnels encouragent ce style, mais Haskell l'impose dans tout code qui ne signale pas explicitement par son type qu'il admet des effets de bord et qui grâce à ce mécanisme en prévient et en circonscrit les dangers.


Exemples de code



Fonction factorielle (récursive)


La définition classique de la fonction factorielle :

fac n | n < 2     = 1
      | otherwise = n * fac (n - 1)

Fonction factorielle (avec product)


La définition élégante de la fonction factorielle (qui utilise la fonction Haskell product et la notation sur les listes) :

fac n = product [1..n]

Fonction factorielle (liste infinie)


Il est également possible de définir une liste de toutes les factorielles :

facs = 1: zipWith (*) facs [1..]

La valeur précédente est une liste infinie, ce qui est tout à fait possible grâce à l'évaluation paresseuse. Grâce à cette liste, on peut implémenter fac de cette manière :

fac n = facs !! n

(!! est un opérateur qui renvoie le n-ième élément d'une liste).

Comme facs est évaluée de manière paresseuse dans fac, un appel à fac n ne provoque que l'évaluation des n premiers termes de facs. Notez que la valeur de chaque élément de facs n'est évaluée qu'une seule fois.


Fonction Fibonacci (naïve)


Une implémentation naïve de la fonction qui retourne le n-ième nombre de la suite de Fibonacci :

fib 0 = 0
fib 1 = 1
fib n = fib (n - 2) + fib (n - 1)

Fonction Fibonacci (liste infinie)


Une fonction qui retourne la liste infinie des nombres de Fibonacci, également grâce à l'évaluation paresseuse :

fibs = 0 : 1 : (zipWith (+) fibs (tail fibs))
fib n = fibs !! n

Contrairement à la version naïve, la complexité d'un appel à fib est linéaire, et ceci grâce à la mémoïsation.

En effet, dans la précédente version les valeurs de fib étaient calculées à chaque demande. Ainsi, un appel à fib 4 provoque un appel à fib 3 et un appel à fib 2, qui eux-mêmes appellent une nouvelle fois fib 2, deux fois fib 1 et une fois fib 0, etc.

En revanche, dans le cas de la liste infinie, chaque valeur de fib n'est calculée qu'une seule fois puis stockée en mémoire.


Recherche de nombres premiers


Grâce au mécanisme de l'évaluation paresseuse, il est également possible de définir la liste entière (et infinie) des nombres premiers :

primes = remDivs [2..]
  where remDivs (x:xs) = x: remDivs [n | n <- xs, (mod n x) /= 0]

Cet algorithme est cependant très inefficace, et une implémentation du crible d'Ératosthène permet de bien meilleures performances[1].

Pour rendre la recherche plus efficace, on peut vérifier que le nombre dont on teste la primalité n’est divisible par aucun des nombres premiers inférieurs à sa racine carrée. Une implémentation en Haskell peut être :

prem = 2:[a | a <- [3,5..], (all (/= 0) (map (\x -> mod a x) (takeWhile (<= truncate(sqrt (fromIntegral a::Float))) prem))) ]

Tri rapide (quicksort)


L'algorithme du tri rapide peut être écrit en Haskell en manipulant des listes :

qsort [] = []
qsort (x:xs) =
  qsort elts_lt_x ++ [x] ++ qsort elts_greq_x
  where
    elts_lt_x = [y | y <- xs, y < x]
    elts_greq_x = [y | y <- xs, y >= x]

Ou

qsort []     = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)

En raison des copies et des concaténations de listes, ce code peut être lent, en fonction du compilateur. Une amélioration consiste à effectuer le test de comparaison une seule fois :

qSort :: (Ord a) => [a] -> [a]
qSort [] = []
qSort (mid:xs) = qSort inf ++eg++ qSort sup
  where (inf, eg, sup) = sep xs ([],[mid],[])
    where 
      sep [] tuple = tuple
      sep (y:ys) (i,e,s)
        | (y < mid)  = sep ys (y:i,e,s)
        | (y == mid) = sep ys (i,y:e,s)
        | otherwise  = sep ys (i,e,y:s)

Ces implémentations naïves du tri rapide présentent cependant l'inconvénient d'être d'une complexité (O(N²)) dans le cas d'une liste triée.


Implémentations


Les implémentations suivantes sont toutes compatibles (ou presque compatibles) avec le standard Haskell 98, et sont distribuées sous licences libres. Toutes les implémentations de Haskell sont à ce jour des logiciels libres.


Quelques utilisations d'Haskell


Parce que non-procédural, Haskell permet de limiter considérablement les besoins de débogage : les déclarations (un programme Haskell ne comporte que des déclarations) étant indépendantes les unes des autres, le programmeur n'a pas à s'occuper d'un quelconque flot de contrôle ni même de la séquence ou du contexte des déclarations ; il arrive donc sans surprise que des projets soient réalisés en Haskell avant d'être disponibles dans d'autres langages. Les exemples les plus connus sont :


Langages similaires à Haskell



Références


  1. « Sieve of Eratosthenes (Haskell) »(Archive.orgWikiwixArchive.isGoogle • Que faire ?), sur LiteratePrograms
  2. (en-US) « Fighting spam with Haskell », sur Facebook Engineering, (consulté le )
  3. « Purescript/documentation », sur GitHub (consulté le ).

Voir aussi


Sur les autres projets Wikimedia :


Articles connexes



Liens externes



Bibliographie



На других языках


- [fr] Haskell

[ru] Haskell

Haskell (МФА: [hæskəl]) — стандартизированный чистый функциональный язык программирования общего назначения. Является одним из самых распространённых языков программирования с поддержкой отложенных вычислений. Система типов — полная, сильная, статическая, с автоматическим выводом типов, основанная на системе типов Хиндли — Милнера. Поскольку язык функциональный, то основная управляющая структура — это функция.



Текст в блоке "Читать" взят с сайта "Википедия" и доступен по лицензии Creative Commons Attribution-ShareAlike; в отдельных случаях могут действовать дополнительные условия.

Другой контент может иметь иную лицензию. Перед использованием материалов сайта WikiSort.org внимательно изучите правила лицензирования конкретных элементов наполнения сайта.

2019-2025
WikiSort.org - проект по пересортировке и дополнению контента Википедии