Le système de types de Haskell est-il un obstacle à la compréhension de la programmation fonctionnelle? [fermé]


33

J'étudie Haskell dans le but de comprendre la programmation fonctionnelle, dans l'espoir d'appliquer les connaissances que j'ai acquises dans d'autres langues (Groovy, Python, JavaScript principalement.)

J'ai choisi Haskell parce que j'avais l'impression qu'il est très purement fonctionnel et ne permet pas de dépendre de l'État.

Je n'ai pas choisi d'apprendre Haskell parce que je m'intéressais à naviguer dans un système de type extrêmement rigide.

Ma question est la suivante: un système de types fort est-il un sous-produit nécessaire d’un langage fonctionnel extrêmement pur, ou s’agit-il d’un choix de conception sans rapport avec Haskell?


6
Si vous ne voulez rien taper explicitement, vous n'avez pas besoin de taper explicitement. Haskell peut en déduire des types parfaitement. Et ce n’est pas comme si vous aviez une seule variable stockant potentiellement deux types incompatibles.
Anon.

4
@Anon oui, mais vos listes doivent être homogènes. Croyez-moi, ce genre de chose peut vous gêner, même avec une inférence de type.
Eric Wilson

13
@ FarmBoy et quel est le problème avec l'utilisation de Maybe? Java vous fait vraiment utiliser Maybe sur toutes les classes, ce qui est étrange.
alternative

3
Et si vous voulez vraiment utiliser une liste hétérogène, vous pouvez bien sûr utiliser des types de données algébriques.
alternative

1
@mathepic à ce stade, nous avons vraiment perdu la trace de ma question initiale, qui était une question parfaitement valable.
Eric Wilson

Réponses:


40

Je crois que comprendre le système de types de Haskell est un amplificateur pour comprendre la programmation fonctionnelle.

Le problème de la programmation purement fonctionnelle est qu’en l’absence d’effets secondaires, qui vous permettent de faire toutes sortes de choses implicitement, une programmation purement fonctionnelle rend la structure de vos programmes beaucoup plus explicite.

Haskell vous empêche de mettre des choses sous le tapis, vous oblige à traiter explicitement la structure de votre programme et vous apprend un langage pour décrire ces structures: le langage des types. Comprendre les types, particulièrement riches comme Haskell, fera de vous un meilleur programmeur dans toutes les langues.

Si Haskell n’était pas fortement typé, des concepts tels que les monades, les foncteurs applicatifs, etc. n'auraient jamais été appliqués à la programmation.


2
C'est une bonne réponse. Mon ajout est que, bien que le système de types puisse sembler inhabituel au début, plus tard, lorsque vous commencerez à apprendre les concepts plus avancés, vous verrez qu'il y a certaines choses qui ne peuvent être faites qu'en raison du respect de ce type. système (ajoutez STM et Data Parallel à la liste ci-dessus). Les choses qui ne seraient pas des starters dans d'autres systèmes de type s'intègrent naturellement avec le système Haskell. Mon conseil: tenez-vous-en à cela pendant un moment, laissez-le s'enfoncer dans le temps (ce n'est pas un langage "cram").
anon

2
Je sais que c'est une très vieille réponse, mais je ne suis vraiment pas d'accord. Je pense que, aussi explicite que puissent être certaines choses dans le langage, le système de types, en particulier avec les monades telles que State et Parsec, balaie une tonne de choses sous le tapis. En réalité, cela interfère beaucoup avec ma capacité à apprendre les bibliothèques de la langue.
Savanni D'Gerinel

4
@ SavanniD'Gerinel: Je pense que dans cette réponse, "mettre les choses sous le tapis" ne signifie pas ajouter une fonctionnalité implicite (ce que fait Haskell de manière contrôlée, par exemple via des monades, et qui permet de réduire le passe-partout), mais permet plutôt un morceau de code. faire quelque chose qu'on ne s'attend pas à faire. Ex: une fonction pure dans Haskell n'aura jamais d'effets secondaires. Période. Dans de nombreuses autres langues, vous pouvez le promettre dans la documentation d'une fonction, mais rien dans votre langue ne vous empêchera de générer des effets secondaires quelque part dans votre code.
Giorgio

33

Le langage fonctionnel le plus dynamiquement typé est sans doute Scheme. Cela dit, le système de types de Haskell est un indicateur de sa pureté. C'est une question de "comment mesurer la pureté?". Le système de types de Haskell vous permet de boucler facilement les actions impures dans IO. Pour ce faire, vous avez besoin d’un système de types statique.

Mais disons que le système de types de Haskell n'a rien à voir avec la programmation fonctionnelle. Il serait tout à fait à la hauteur de l'hybris de prétendre que le système de typage ne vous aiderait pas dans cette entreprise éducative. Le système de types de Haskell est riche et complexe, et d'autant plus intéressant qu'il est comparé aux systèmes de types de C ++ et OCaml.

Est-ce un obstacle? Non, je pense que c'est un atout. Essayez de réfléchir à la façon de gérer la paresse de Haskell sans, IOpar exemple.


8
Le système de type +1 de Haskell peut être votre ami une fois que vous vous y êtes habitué.
Larry Coleman

"Pour faire cela, vous avez besoin d’un système de type statique". Vraiment?
Jon Harrop

1
"d'autant plus intéressant par rapport aux systèmes de types de C ++ et OCaml". Avez-vous étudié les modules d'ordres supérieurs d'OCaml de première classe, le système d'objets déduits et les variants polymorphes structurellement typés?
Jon Harrop

2
@JonHarrop ou un système d'effet ou un moyen de mesurer / évaluer la pureté. Oui, c'est pourquoi il est intéressant de les comparer. Différents choix font pour différentes langues.
Logan Capaldo

20

Clojure est typé de manière dynamique et presque aussi pur que Haskell. Il est donc bon de dire que le système de types de Haskell était davantage un choix de conception qu'un impératif absolu. Les deux ont définitivement leurs points forts, donc vous pouvez envisager Clojure si vous n'aimez vraiment pas la rigidité de Haskell (mais voir ci-dessous).

Lorsque j'ai commencé à utiliser Haskell, je considérais que le système de types était gênant et je ne le tolérais qu'en raison de l'inférence de type. J'ai vite découvert que le compilateur se plaignait de nombreuses erreurs de type, même si le compilateur m'avait laissé le faire (par exemple, en utilisant accidentellement map au lieu de concatMap). J'ai ensuite découvert que les programmes qui passaient la vérification de type étaient généralement corrects, ou du moins proches de la correction. J'ai même eu une phase paresseuse où j'ai refactorisé en changeant un type de fonction et en laissant le compilateur me dire ce qu'il fallait changer. Finalement, j'ai réalisé que le système de types de Haskell était en fait très expressif et j'ai commencé à concevoir mes programmes autour des types. C'est le Saint Graal de Haskell.


Une autre chose à noter: j'ai appris la programmation fonctionnelle en utilisant à la fois Scheme et Haskell à peu près au même moment (le premier pour une classe et le second pour le plaisir). J'ai trouvé que la récursion était beaucoup plus facile avec la correspondance de motifs de Haskell qu'avec ifs et conds dans Scheme, qui, je suppose, est également transmis à Clojure.
Tikhon Jelvis

@ Larry Coleman: +1 pour décrire avec précision ma propre expérience avec les systèmes de types: d'abord C ++, puis Ocaml et maintenant mon propre langage, Felix. Oui, je refactifie toujours en traquant les erreurs du compilateur.
Yttrill

8

Le système de types de Haskell est essentiel pour sa capacité à isoler les effets du code pur. À moins que vous ne puissiez isoler les effets d’une autre manière ou que vous ne supprimiez aucun effet, un système de type statique fort est indispensable à la programmation purement fonctionnelle.

Haskell est un très bon exemple de langage doté d'un système de type statique fort. Si vous souhaitez une formation large et complète en informatique et en conception de langage de programmation en particulier, Haskell serait un excellent choix parmi les langues que vous devriez apprendre.

Le système de types ne devrait pas être un obstacle énorme. Les personnes qui programment ont tendance, même lorsqu'elles utilisent des langages dynamiques, à suivre les conventions de frappe pouvant être encodées à l'aide du système de frappe de Haskell. Haskell propose également une inférence de type qui atténue la verbosité par rapport à des langages tels que C ++ et Java. Lorsque vous recevez un message d'erreur, le compilateur vous dit seulement au moment de la compilation ce qu'un langage avec des types dynamiques vous dirait au moment de l'exécution.

L'opposé d'un système de type dynamique est un système de type statique et non un système de type fort. Un système de type fort est l'opposé d'un système de type faible.


1
Par exemple, C est typé statiquement mais faiblement. Vous avez des types, mais il est facile de subvertir complètement le système de types, de jouer avec les représentations sous-jacentes spécifiques à une machine, etc. De nombreux langages dynamiquement typés OTOH sont assez fortement typés - peu d'incantations implicites, peu de moyens (le cas échéant) de subvertir le système de types.
Steve314

4

Il vous dit tout de suite lorsque vous faites des erreurs stupides. C'est utile. J'ai travaillé dans Racket (Scheme) ce dernier trimestre et, à plusieurs reprises, j'ai réussi un s-exp non analysé dans lequel je m'attendais à une fonction analysée de mon interprète. suite de test de taille moyenne. Si j'avais du typage statique, cela aurait immédiatement été porté à mon attention.

Bien sûr, les erreurs de logique ne peuvent pas vraiment être capturées par le système de types, mais le nombre de façons de gâcher vous-même est considérablement réduit.

De plus, l'inférence de type vous permet d'ignorer le système de types si vous le souhaitez. Il est toujours là, mais cela ne nécessite pas une participation active de votre part. Il est toujours utile de comprendre les types de vos fonctions, mais un code correct fonctionnera correctement.

La pureté de Haskell est codée dans son système de types. La monade IO est une construction de niveau type qui empêche le code impur de s'infiltrer dans des fonctions pures. La pureté est donc garantie par le système de types.


8
Si vous pensez que vous pouvez ignorer le système de typage de Haskell, alors je pense que vous n'avez pas beaucoup codé Haskell.
Eric Wilson

Pas ignorer autant qu'ignorer autant que de taper la fonction, de la charger dans GHCi, et d'aller dessus. Mais vous allez encore avoir besoin de saupoudrer certaines fonctions fromIntegral ou autres de temps en temps.
Théo Belaire

1
Même avec l’inférence de type, 90% des fonctions d’Haskell codées et codées font en sorte que les maudits éléments s’enchevêtrent, ce qui nécessite une compréhension de son système de types et de ses messages d’erreur erronés. Même ": t" n'est pas une solution magique, c'est juste la première étape pour comprendre comment faire compiler le programme.
Andres F.

Eh bien, certaines parties sont en désordre, je suis d’accord. Je pense vraiment que le contenu numérique du prélude pourrait être nettoyé et corrigé, car, dans sa forme actuelle, c'est un désordre épouvantable. Mais la plupart des aspects fonctionnels clés sont assez propres. map, filter, foldr / l et d'autres fonctions fonctionnelles amusantes fonctionnent plutôt bien.
Théo Belaire

2

Être un langage "fonctionnel" signifie (en dehors d’autres choses) que les fonctions sont des objets de première classe dans le langage.

Être un langage "pur" signifie que les fonctions sont des fonctions mathématiques (par opposition aux procédures) - si elles ont la même entrée, elles produisent toujours la même sortie.

Un "langage purement fonctionnel" est un langage dans lequel les deux éléments ci-dessus sont valables. Je ne suis pas au courant d'une « Pure - ly langue fonctionnelle ».

Un système de type fort est une propre façon d'avoir une langue pure et pratique. Les types aident le compilateur à comprendre les optimisations, en plus d’assurer la correction. (Mais ce n’est pas le seul moyen - clojure est pur, mais n’a pas un système de type aussi fort que Haskell.)

Si le système de caractères vous dérange, je vous suggère d'essayer un langage plus dynamique, tel que Scheme, ou d'utiliser le système d'inférence de types de Haskell.


0

Oui, le système de types est un atout incroyable. Il serait très difficile de décrire même le fonctionnement des monades ou le fonctionnement de certains combinateurs sans le système de type. Considérez combien de tutoriels sur Haskell vous demandent d’abord de considérer le type de la fonction en question avec a: t au niveau de la réplique. Ce n'est tout simplement pas disponible pour vous dans un langage typé dynamiquement. Bien sûr, toute la complexité du système de types est toujours là. Une monade est toujours une monade. Mais la langue a décidé de se laver les mains et de ne fournir aucune aide. Vous êtes seul, mon pote. Je ne frappe pas des langues à typage dynamique. Je les aime beaucoup. Scheme est un outil puissant par excellence. Mais vous remarquerez que lorsque nous parlons de choses comme des monades dans des langages dynamiques, nous inventons souvent une notationpour décrire le type de procédures. Un programmeur fonctionnel se battra avec les types d'une manière ou d'une autre. Le vérificateur de caractères de Haskell vous donne simplement de bons outils pour apprendre à le faire.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.