web-dev-qa-db-fra.com

Comment concevez-vous des programmes en Haskell ou dans d'autres langages de programmation fonctionnels?

J'ai une certaine expérience dans les langages de programmation orientés objet comme c # ou Ruby. Je sais comment concevoir un programme dans un style orienté objet, comment créer des classes et des objets, et comment définir des relations entre eux. Je connais également certains modèles de conception.

Comment les gens écrivent-ils des programmes fonctionnels? Comment commencent-ils? Existe-t-il des modèles de conception pour les langages fonctionnels? Les méthodologies comme la programmation extrême ou le développement agile sont-elles applicables aux langages fonctionnels?

52
Luke

J'écris ma réponse principalement avec Haskell à l'esprit, bien que de nombreux concepts s'appliquent également à d'autres langages fonctionnels comme Erlang, LISP (s) et ML. Certains s'appliquent même (dans une certaine mesure) à Ruby, Python, Perl et Javascript.

Comment les gens écrivent-ils des programmes fonctionnels? Comment commencent-ils?

En écrivant des fonctions. Lorsque vous effectuez une programmation fonctionnelle, soit vous écrivez main, soit vous écrivez une fonction d'assistance. Parfois, votre objectif principal peut être d'écrire un type de données avec diverses fonctions pertinentes qui fonctionnent dessus.

La programmation fonctionnelle est très bien adaptée aux approches descendantes et ascendantes. Haskell encourage fortement l'écriture de vos programmes dans un langage de haut niveau, puis la simple définition des détails de votre conception de haut niveau. Voir minimum, par exemple:

minimum    :: (Ord a) => [a] -> a
minimum xs =  foldl1 min xs

La fonction pour trouver le plus petit élément dans une liste est écrite simplement comme une traversée de la liste, en utilisant la fonction min pour comparer chaque élément avec l '"accumulateur", ou la valeur minimale actuelle.

Existe-t-il des modèles de conception pour les langages fonctionnels?

Il y a deux choses qui pourraient être assimilées à des "modèles de conception", à mon humble avis, fonctions d'ordre supérieur et monades. Parlons du premier. Les fonctions d'ordre supérieur sont des fonctions qui prennent d'autres fonctions en entrée ou produisent des fonctions en sortie. Tout langage fonctionnel fait généralement un usage intensif de map, filter et fold (le pli est souvent aussi appelé "réduire"): trois fonctions très basiques d'ordre supérieur qui appliquent un fonctionner à une liste de différentes manières. Celles-ci remplacent d'une manière magnifique le passe-partout pour les boucles. Passer des fonctions comme paramètres est une aubaine extrêmement puissante pour la programmation; de nombreux "modèles de conception" peuvent être réalisés plus simplement en utilisant des fonctions d'ordre supérieur, en pouvant créer les vôtres et en exploitant la puissante bibliothèque standard, qui regorge de fonctions utiles.

Les monades sont le sujet "le plus effrayant". Mais ils ne sont pas vraiment si effrayants. Ma façon préférée de penser aux monades est de les considérer comme enveloppant une fonction dans une bulle et donnant à cette fonction des super pouvoirs (qui ne fonctionnent qu'à l'intérieur de la bulle). Je pourrais élaborer, mais le monde n'a pas vraiment besoin d'une autre analogie de la monade. Je vais donc passer à des exemples rapides. Supposons que je veuille utiliser un "modèle de conception" non déterministe. Je veux exécuter le même calcul pour différentes entrées différentes en même temps. Je ne veux pas choisir une seule entrée, je veux les choisir toutes. Ce serait la monade de liste:

allPlus2 :: [Int] -> [Int]
allPlus2 xs = do x <- xs
                 return (x + 2)

Maintenant, la façon idiomatique d'effectuer cela est en fait map, mais à titre d'illustration, pouvez-vous voir comment la liste monad m'a permis d'écrire une fonction qui semble fonctionner sur une valeur, mais l'a dotée de la superpuissance travailler sur chaque élément d'une liste? D'autres superpuissances incluent l'échec, l'état, l'interaction avec le "monde extérieur" et l'exécution parallèle. Ces superpuissances sont très puissantes et la plupart des langages de programmation permettent aux fonctions dotées de superpuissances de se déchaîner tout autour. La plupart des gens disent que Haskell n'autorise pas du tout ces superpuissances, mais en réalité, Haskell les contient simplement dans des monades afin que leur effet puisse être limité et observé.

tl; dr Les fonctions et monades d'ordre supérieur Grokking sont l'équivalent Haskell des modèles de conception grokking. Une fois que vous avez appris ces concepts Haskell, vous commencez à penser que les "modèles de conception" sont principalement des solutions de contournement bon marché pour simuler la puissance de Haskell.

Les méthodologies comme la programmation extrême ou le développement agile sont-elles applicables aux langages fonctionnels?

Je ne vois rien qui lie ces stratégies de gestion à un seul paradigme de programmation. Comme l'a déclaré Phynfo, la programmation fonctionnelle pratiquement force vous à faire la décomposition des fonctions, brisant un gros problème en sous-problèmes, donc les mini-jalons devraient être un jeu d'enfant. Il existe des outils comme QuickCheck et Zeno pour tester ou même prouver les propriétés des fonctions que vous écrivez.

24
Dan Burton