J'ai fait quelques lectures légères sur les concepts et les idées de programmation fonctionnelle. Jusqu'à présent, tout va bien, j'ai lu trois concepts principaux: les structures algébriques, les classes de types et les types de données algébriques. J'ai une assez bonne compréhension de ce que sont les types de données algébriques. Je pense que les types de somme et les types de produits sont assez simples. Par exemple, je peux imaginer créer un type de données algébrique comme un type Card qui est un type de produit composé de deux types enum, Suit (avec quatre valeurs et symboles) et Rank (avec 13 valeurs et symboles).

Cependant, je suis toujours accro à essayer de comprendre précisément ce que sont les structures algébriques et les classes de types. J'ai juste une image au niveau de la surface dans ma tête, mais je n'arrive pas à comprendre complètement, par exemple, les différents types de structures algébriques comme les foncteurs, les monoïdes, les monades, etc. En quoi sont-ils exactement différents? Comment peuvent-ils être utilisés dans un cadre de programmation? En quoi les classes de types sont-elles différentes des classes régulières? Quelqu'un peut-il au moins m'indiquer la direction d'un bon livre sur l'algèbre abstraite et la programmation fonctionnelle? Quelqu'un m'a recommandé d'apprendre Haskell, mais ai-je vraiment besoin d'apprendre Haskell pour comprendre la programmation fonctionnelle?

5
typical danny 30 août 2020 à 11:19

2 réponses

Meilleure réponse

La "structure algébrique" est un concept qui va bien au-delà de la programmation, il appartient aux mathématiques.

Imaginez la mer insondable et profonde de tous les objets mathématiques possibles. Numéros de chaque bande (les naturels, les reals, p-adic < / a> nombres ...) sont là, mais aussi des choses comme des séquences de lettres, des graphiques , arbres, symétries des figures géométriques, et toutes les transformations et mappages bien définis entre eux. Et bien plus encore.

Nous pouvons essayer de «jeter un filet» dans cette mer et ne retenir que certaines de ces entités, en spécifiant les conditions. Comme "des collections de choses, pour lesquelles il y a une opération qui combine deux de ces choses en une troisième chose du même type, et pour lesquelles l'opération est associative". Nous pouvons donner à ces conditions leur propre nom, comme, par exemple, "semigroup". (Parce que nous parlons de choses très abstraites, il est difficile de choisir un nom descriptif.)

Cela laisse de côté de nombreux habitants de la «mer» mathématique, mais la description convient toujours à beaucoup d'entre eux! De nombreuses collections d'objets sont des semi-groupes. Les nombres naturels avec l'opération de multiplication par exemple, mais aussi les listes non vides de lettres avec concaténation, ou le symétries d'un carré avec composition.

Vous pouvez développer votre description avec des conditions supplémentaires. Comme "un semigroupe, et il y a aussi un élément tel que le combiner avec n'importe quel autre élément donne l'autre élément, inchangé". Cela limite le nombre d'entités mathématiques qui correspondent à la description, car vous en exigez plus. Certains semigroupes valides manqueront cet "élément neutre". Mais beaucoup d'entités mathématiques satisferont toujours la description développée. Si vous ne faites pas attention, vous pouvez déclarer des conditions si restrictives qu'aucune entité mathématique possible ne peut les adapter! À d'autres moments, vous pouvez être si précis que une seule entité leur convient.

En travaillant uniquement avec ces descriptions d'entités mathématiques, en utilisant uniquement les propriétés générales dont nous avons besoin, nous pouvons obtenir des résultats inattendus < / a> à leur sujet, non évidents à première vue, des résultats qui s'appliqueront à toutes les entités qui correspondent à la description. Considérez ces découvertes comme l'équivalent mathématique de la «réutilisation de code». Par exemple, si nous savons qu'une collection d'objets est un semi-groupe, nous pouvons calculer les exponentiels en utilisant exponentiation binaire au lieu de combiner fastidieusement une chose avec elle-même n fois. Mais cela ne fonctionne que grâce à la propriété associative de l'opération semigroup.

11
danidiaz 30 août 2020 à 14:41

Vous avez posé plusieurs questions ici, mais je peux essayer d'y répondre du mieux que je peux:

… Différents types de structures algébriques comme les foncteurs, les monoïdes, les monades, etc. En quoi sont-ils exactement différents? Comment peuvent-ils être utilisés dans un cadre de programmation?

C'est une question très courante lors de l'apprentissage de Haskell. Je n’écrirai pas encore une autre réponse ici - et une réponse complète est de toute façon assez longue - mais une simple recherche sur Google donne de très bonnes réponses: par exemple Je peux recommander 1 2 3

En quoi les classes de types sont-elles différentes des classes régulières?

(Par «classes régulières», je suppose que vous entendez des classes telles qu’elles se trouvent dans la POO.)

Ceci est une autre question courante. Fondamentalement, les deux n'ont presque rien en commun sauf le nom. Une classe en POO est une combinaison de champs et méthodes . Les classes sont utilisées en créant des instances de cette classe; chaque instance peut stocker des données dans ses champs et manipuler ces données à l'aide de ses méthodes.

En revanche, une classe de type est simplement une collection de fonctions (souvent également appelées méthodes , bien qu’il n’y ait pratiquement pas de connexion). Vous pouvez déclarer une instance d'une classe de type pour un type de données (encore une fois, pas de connexion) en redéfinissant chaque méthode de la classe pour ce type, après quoi vous pouvez utiliser les méthodes avec ce type. Par exemple, la classe Eq ressemble à ceci:

class Eq a where
    (==) :: a -> a -> Bool
    (/=) :: a -> a -> Bool

Et vous pouvez définir une instance de cette classe pour, disons, Bool, en implémentant chaque fonction:

instance Eq Bool where
    True == True   = True
    False == False = True
    _ == _         = False

    p /= q = not (p == q)

Quelqu'un peut-il au moins m'indiquer la direction d'un bon livre sur l'algèbre abstraite et la programmation fonctionnelle?

Je dois admettre que je ne peux pas vous aider avec cela (et de toute façon, c'est hors sujet pour Stack Overflow).

Quelqu'un m'a recommandé d'apprendre Haskell, mais ai-je vraiment besoin d'apprendre Haskell pour comprendre la programmation fonctionnelle?

Non, vous ne pouvez pas apprendre la programmation fonctionnelle à partir de n'importe quel langage fonctionnel, y compris Lisp (en particulier les dialectes Scheme), OCaml, F #, Elm, Scala etc. Haskell se trouve être un langage de programmation fonctionnel particulièrement `` pur '', et je le ferais le recommande également, mais si vous voulez juste apprendre et comprendre la programmation fonctionnelle, n'importe lequel de ceux-ci fera l'affaire.

7
bradrn 30 août 2020 à 09:16