Maison > Article > interface Web > Programmation fonctionnelle en TypeScript
Vous pouvez trouver le code source ici : https://github.com/aelassas/Functional-ts
Dans TypeScript, les fonctions ne sont que des objets. Par conséquent, les fonctions peuvent être construites, passées en paramètre, renvoyées par des fonctions ou affectées à des variables. Ainsi, TypeScript possède des fonctions de premier ordre. Plus précisément, TypeScript prend en charge les éléments suivants :
Cet article n'abordera pas les bases de la programmation fonctionnelle, car vous pouvez trouver de nombreuses ressources sur ce sujet sur Internet. Au lieu de cela, il parlera de programmation fonctionnelle en TypeScript appliquée à l'algèbre, aux nombres, au plan euclidien et aux fractales. Les exemples fournis dans cet article vont du plus simple au plus complexe, mais toujours illustrés de manière simple, directe et facile à comprendre.
Pour exécuter le code source, vous devrez installer Node.js. Une fois Node.js installé, téléchargez l'archive du code source, décompressez-la, accédez au dossier du code source que vous avez décompressé sur un terminal, configurez l'environnement TypeScript et installez toutes les dépendances nécessaires avec la commande suivante :
npm install
Pour exécuter la démo de Numbers, exécutez la commande suivante :
npm run numbers
Pour exécuter la démo du plan euclidien, exécutez la commande suivante :
npm run plane
Pour exécuter la démo de fractals, exécutez la commande suivante :
npm run fractals
Soit S n'importe quel ensemble d'éléments a, b, c ... (par exemple, les livres sur la table ou les points du plan euclidien) et soit S' n'importe quel sous-ensemble de ces éléments (par exemple, le livres verts sur la table ou les points du cercle de rayon 1 centré à l'origine du plan euclidien).
La Fonction Caractéristique S'(x) de l'ensemble S' est une fonction qui associe soit vrai, soit faux à chaque élément x de S.
S'(x) = true if x is in S' S'(x) = false if x is not in S'
Soit S l'ensemble des livres sur la table et soit S' l'ensemble des livres verts sur la table. Soit a et b deux livres verts, et c et d deux livres rouges sur la table. Alors :
npm install
Soit S l'ensemble des points du plan euclidien et soit S' l'ensemble des points du cercle de rayon 1 centré à l'origine du plan euclidien (0, 0) (cercle unité). Soient a et b deux points du cercle unité, et c et d deux points d'un cercle de rayon 2 centré à l'origine du plan euclidien. Alors :
npm run numbers
Ainsi, tout ensemble S' peut toujours être représenté par sa Fonction caractéristique. Une fonction qui prend en argument un élément et renvoie vrai si cet élément est dans S', faux sinon. En d'autres termes, un ensemble (type de données abstrait) peut être représenté via une fonction dans TypeScript.
npm run plane
Dans les prochaines sections, nous verrons comment représenter certains ensembles fondamentaux dans l'algèbre des ensembles via TypeScript de manière fonctionnelle, puis nous définirons des opérations binaires génériques sur les ensembles. Nous appliquerons ensuite ces opérations sur des nombres puis sur des sous-ensembles du plan euclidien. Les ensembles sont des structures de données abstraites, les sous-ensembles de nombres et les sous-ensembles du plan euclidien sont la représentation de structures de données abstraites, et enfin les opérations binaires sont la logique générique qui fonctionne sur toute représentation des structures de données abstraites.
Cette section présente la représentation de certains ensembles fondamentaux dans l'algèbre des ensembles via TypeScript.
Soit E l'ensemble vide et Vide sa Fonction caractéristique. En algèbre des ensembles, E est l'unique ensemble ne comportant aucun élément. Par conséquent, Empty peut être défini comme suit :
npm run fractals
Ainsi, la représentation de E en TypeScript peut être définie comme suit :
S'(x) = true if x is in S' S'(x) = false if x is not in S'
En algèbre des ensembles, le Vide est représenté comme suit :
Ainsi, exécutez le code ci-dessous :
S'(a) = S'(b) = true S'(c) = S'(d) = false
donne les résultats suivants :
Soit S un ensemble et S' le sous-ensemble de S qui contient tous les éléments et toute sa Fonction caractéristique. En algèbre des ensembles, S' est l'ensemble complet qui contient tous les éléments. Par conséquent, Tout peut être défini comme ceci :
S'(a) = S'(b) = true S'(c) = S'(d) = false
Ainsi, la représentation de S' en TypeScript peut être définie comme suit :
type Set<T> = (x: T) => boolean
En algèbre des ensembles, Tout est représenté comme suit :
Ainsi, exécutez le code ci-dessous :
npm install
donne les résultats suivants :
Soit E l'ensemble Singleton et Singleton sa Fonction caractéristique. En algèbre des ensembles, E également connu sous le nom d'ensemble unitaire, ou 1-tuple est un ensemble avec exactement un élément e. Par conséquent, Singleton peut être défini comme suit :
npm run numbers
Ainsi, la représentation de E en TypeScript peut être définie comme suit :
npm run plane
Ainsi, exécutez le code ci-dessous :
npm run fractals
donne les résultats suivants :
Cette section présente des sous-ensembles de l'ensemble des entiers.
Soit E l'ensemble des nombres pairs et Pair sa Fonction caractéristique. En mathématiques, un nombre pair est un nombre multiple de deux. Par conséquent, Even peut être défini comme suit :
S'(x) = true if x is in S' S'(x) = false if x is not in S'
Ainsi, la représentation de E en TypeScript peut être définie comme suit :
S'(a) = S'(b) = true S'(c) = S'(d) = false
Ainsi, exécutez le code ci-dessous :
S'(a) = S'(b) = true S'(c) = S'(d) = false
donne les résultats suivants :
Soit E l'ensemble des nombres impairs et Odd sa Fonction caractéristique. En mathématiques, un nombre impair est un nombre qui n'est pas un multiple de deux. Par conséquent, Odd peut être défini comme suit :
type Set<T> = (x: T) => boolean
Ainsi, la représentation de E en TypeScript peut être définie comme suit :
Empty(x) = false if x is in E Empty(x) = false if x is not in E
Ainsi, exécutez le code ci-dessous :
const empty = () => (e: T) => false
donne les résultats suivants :
Soit E l'ensemble des multiples de 3 et MultipleOfThree sa Fonction caractéristique. En mathématiques, un multiple de 3 est un nombre divisible par 3. Par conséquent, MultipleOfThree peut être défini comme suit :
console.log('\nEmpty set:') console.log('Is 7 in {}?', common.empty()(7))
Ainsi, la représentation de E en TypeScript peut être définie comme suit :
All(x) = true if x is in S
Ainsi, exécutez le code ci-dessous :
const all = () => (e: T) => true
donne les résultats suivants :
Soit E l'ensemble des multiples de 5 et MultipleOfFive sa Fonction caractéristique. En mathématiques, un multiple de 5 est un nombre divisible par 5. Par conséquent, MultipleOfFive peut être défini comme suit :
npm install
Ainsi, la représentation de E en TypeScript peut être définie comme suit :
npm run numbers
Ainsi, exécutez le code ci-dessous :
npm run plane
donne les résultats suivants :
Il y a longtemps, lorsque je jouais avec les problèmes du Projet Euler, je devais résoudre le suivant :
npm run fractals
Pour résoudre ce problème, j'ai d'abord dû écrire un algorithme rapide qui vérifie si un nombre donné est premier ou non. Une fois l'algorithme écrit, j'ai écrit un algorithme itératif qui parcourt les nombres premiers jusqu'à ce que le 10 001ème nombre premier soit trouvé.
Soit E l'ensemble des nombres premiers et Prime sa Fonction caractéristique. En mathématiques, un nombre premier est un nombre naturel supérieur à 1 qui n'a pas de diviseur positif autre que 1 et lui-même. Par conséquent, Prime peut être défini comme suit :
S'(x) = true if x is in S' S'(x) = false if x is not in S'
Ainsi, la représentation de E en TypeScript peut être définie comme suit :
S'(a) = S'(b) = true S'(c) = S'(d) = false
Ainsi, exécutez le code ci-dessous pour résoudre notre problème :
S'(a) = S'(b) = true S'(c) = S'(d) = false
où getPrime est défini ci-dessous :
type Set<T> = (x: T) => boolean
donne les résultats suivants :
Cette section présente plusieurs opérations fondamentales pour construire de nouveaux ensembles à partir d'ensembles donnés et pour manipuler des ensembles. Ci-dessous le diagramme de Ven dans l'algèbre des ensembles.
Soit E et F deux ensembles. L'union de E et F, notée E U F est l'ensemble de tous les éléments qui sont membres de E et F.
Que l'Union soit l'opération syndicale. Ainsi, l'opération Union peut être implémentée comme suit dans TypeScript :
Empty(x) = false if x is in E Empty(x) = false if x is not in E
Exécuter le code ci-dessous :
const empty = () => (e: T) => false
donne les résultats suivants :
Soit E et F deux ensembles. L'intersection de E et F, notée E n F est l'ensemble de tous les éléments qui sont membres à la fois de E et de F.
Soit Intersection l'opération intersection. Ainsi, l'opération Intersection peut être implémentée comme suit dans TypeScript :
console.log('\nEmpty set:') console.log('Is 7 in {}?', common.empty()(7))
Exécuter le code ci-dessous :
All(x) = true if x is in S
donne les résultats suivants :
Soit E et F deux ensembles. Le produit cartésien de E et F, noté E × F est l'ensemble de toutes les paires ordonnées (e, f) telles que e est membre de E et f est membre de F.
Soit CartesianProduct l'opération produit cartésien. Ainsi, l'opération CartesianProduct peut être implémentée comme suit dans TypeScript :
npm install
Exécuter le code ci-dessous :
npm run numbers
donne les résultats suivants :
Soit E et F deux ensembles. Le Complément relatif de F dans E, noté E F est l'ensemble de tous les éléments qui sont membres de E mais non membres de F.
Soit Complément l'opération Complément relatif. Ainsi, l'opération Complément peut être implémentée comme suit dans TypeScript :
npm run planeExécuter le code ci-dessous :
npm run fractals
donne les résultats suivants :
Soit E et F deux ensembles. La différence symétrique de E et F, notée E Δ F est l'ensemble de tous les éléments qui sont membres de E et F mais pas à l'intersection de E et F.
Soit SymmetricDifference l'opération différence symétrique. Ainsi, l'opération SymmetricDifference peut être implémentée de deux manières dans TypeScript. Une manière triviale consiste à utiliser les opérations d'union et de complément comme suit :
S'(x) = true if x is in S' S'(x) = false if x is not in S'
Une autre façon consiste à utiliser l'opération binaire XOR comme suit :
S'(a) = S'(b) = true S'(c) = S'(d) = false
Exécuter le code ci-dessous :
S'(a) = S'(b) = true S'(c) = S'(d) = false
donne les résultats suivants :
Cette section présente d'autres opérations binaires utiles sur les ensembles.
Soit Contient l'opération qui vérifie si un élément est ou non dans un ensemble. Cette opération est une fonction qui prend en paramètre un élément et renvoie vrai si l'élément est dans l'ensemble, faux sinon.
Ainsi, cette opération est définie comme suit en TypeScript :
type Set<T> = (x: T) => boolean
Par conséquent, exécutez le code ci-dessous :
npm install
donne le résultat suivant :
Soit Add l'opération qui ajoute un élément à un ensemble. Cette opération est une fonction qui prend en paramètre un élément et l'ajoute à l'ensemble.
Ainsi, cette opération est définie comme suit en TypeScript :
npm run numbers
Par conséquent, exécutez le code ci-dessous :
npm run plane
donne le résultat suivant :
Soit Remove l'opération qui supprime un élément d'un ensemble. Cette opération est une fonction qui prend en paramètre un élément et le supprime de l'ensemble.
Ainsi, cette opération est définie comme suit en TypeScript :
npm run fractals
Par conséquent, exécutez le code ci-dessous :
S'(x) = true if x is in S' S'(x) = false if x is not in S'
donne le résultat suivant :
Vous pouvez voir avec quelle facilité nous pouvons faire de l'algèbre d'ensembles dans TypeScript grâce à la Programmation fonctionnelle. Dans les sections précédentes, nous avons présenté les définitions les plus fondamentales. Mais, Si vous souhaitez aller plus loin, vous pouvez penser à :
Dans la section précédente, les concepts fondamentaux sur les ensembles ont été implémentés en TypeScript. Dans cette section, nous mettrons en pratique les concepts mis en œuvre sur le plan euclidien.
Un disque est un sous-ensemble d'un plan délimité par un cercle. Il existe deux types de disques. Les disques Fermés qui sont des disques qui contiennent les points du cercle qui constitue sa limite, et les disques Ouverts qui sont des disques qui ne contiennent pas les points du cercle qui constitue sa limite.
Dans cette section, nous allons mettre en place la Fonction Characterstic du disque Fermé et la dessiner dans une page HTML5.
Pour configurer la Fonction caractéristique, nous avons d'abord besoin d'une fonction qui calcule la Distance euclidienne entre deux points du plan. Cette fonction est implémentée comme suit :
S'(a) = S'(b) = true S'(c) = S'(d) = false
où Point est défini ci-dessous :
S'(a) = S'(b) = true S'(c) = S'(d) = false
Cette formule est basée sur le théorème de Pythagore.
où c est la Distance euclidienne, a² est (p1.X - p2.X)² et b² est (p1.Y - p2.Y)².
Soit Disk la Fonction caractéristique d'un disque fermé. En algèbre des ensembles, la définition d'un disque fermé dans l'ensemble des réels est la suivante :
où a et b sont les coordonnées du centre et R le rayon.
Ainsi, l'implémentation de Disk dans TypeScript est la suivante :
npm install
Afin de visualiser l'ensemble dans une page HTML5, j'ai décidé d'implémenter une fonction draw qui dessine un ensemble dans le plan euclidien. J'ai choisi HTML5 et j'ai donc utilisé l'élément canvas pour dessiner.
J'ai ainsi construit le Plan euclidien illustré ci-dessous grâce à la méthode draw.
Ci-dessous la mise en place de l'avion.
npm run numbers
Dans la fonction dessiner, un canevas ayant la même largeur et la même hauteur que le conteneur Plan euclidien est créé. Ensuite chaque point en pixels (x,y) du canevas est remplacé par un point noir s'il appartient à l'ensemble. xMin, xMax, yMin et yMax sont les valeurs limites illustrées dans la figure du Plan euclidien ci-dessus.
Exécuter le code ci-dessous :
npm run plane
où disk est l'identifiant du canevas :
npm run fractals
donne le résultat suivant :
Un demi-plan horizontal ou vertical est l'un des deux sous-ensembles en lesquels un plan divise l'espace euclidien. Un demi-plan horizontal est l'un des deux sous-ensembles en lesquels un plan divise l'espace euclidien par une ligne perpendiculaire à l'axe Y comme dans la figure ci-dessus. Un demi-plan vertical est l'un des deux sous-ensembles en lesquels un plan divise l'espace euclidien par une ligne perpendiculaire à l'axe X.
Dans cette section, nous allons mettre en place les Fonctions caractéristiques des demi-plans horizontal et vertical, les dessiner dans une page HTML5 et voir ce que nous pouvons le faire si nous les combinons avec le sous-ensemble disque.
Soit HorizontalHalfPlane la Fonction caractéristique d'un demi-plan horizontal. L'implémentation de HorizontalHalfPlane dans TypeScript est la suivante :
S'(x) = true if x is in S' S'(x) = false if x is not in S'
Ainsi, exécutez le code ci-dessous :
npm install
où hhp est l'identifiant du canevas :
npm run numbers
donne le résultat suivant :
Soit VerticalHalfPlane la Fonction caractéristique d'un demi-plan vertical. L'implémentation de VerticalHalfPlane dans TypeScript est la suivante :
npm run planeAinsi, en exécutant le code ci-dessous :
npm run fractals
où vhd est l'identifiant du canevas :
S'(x) = true if x is in S' S'(x) = false if x is not in S'
donne le résultat suivant :
Dans la première section de l'article, nous mettons en place des opérations binaires de base sur les ensembles. Ainsi, en combinant l'intersection d'un disque et d'un demi-plan par exemple, on peut dessiner le sous-ensemble demi-disque.
Par conséquent, exécutez l'exemple ci-dessous :
S'(a) = S'(b) = true S'(c) = S'(d) = false
où hd est l'identifiant du canevas :
S'(a) = S'(b) = true S'(c) = S'(d) = false
donne le résultat suivant :
Cette section présente les fonctions sur les ensembles dans le plan euclidien.
Soit TranslatePoint la fonction qui traduit un point dans le plan. En géométrie euclidienne, TranslatePoint est une fonction qui déplace un point donné d'une distance constante dans une direction spécifiée. Ainsi l'implémentation dans TypeScript est la suivante :
type Set<T> = (x: T) => boolean
où (deltax, deltay) est le vecteur constant de la traduction.
Soit traduire la fonction qui traduit un ensemble dans le plan. Cette fonction est simplement implémentée comme suit dans TypeScript :
Empty(x) = false if x is in E Empty(x) = false if x is not in E`translate` prend comme paramètres `deltax` qui est la distance delta dans la première dimension euclidienne et `deltay` qui est la distance delta dans la deuxième dimension euclidienne. Si un point _P (x, y)_ est translaté dans un ensemble _S_, alors ses coordonnées changeront en _(x', y') = (x, delatx, y, deltay)_. Ainsi, le point _(x' - delatx, y' - deltay)_ appartiendra toujours à l'ensemble _S_. En algèbre des ensembles, « traduire » est appelé isomorphe, en d'autres termes, l'ensemble de toutes les traductions forme le _groupe de traduction T_, qui est isomorphe à l'espace lui-même. Ceci explique la logique principale de la fonction. Ainsi, exécutez le code ci-dessous dans notre page HTML5 :
const empty = () => (e: T) => false
où ep_op est l'identifiant du canevas :
console.log('\nEmpty set:') console.log('Is 7 in {}?', common.empty()(7))
donne le résultat suivant :
Soit scalePoint la fonction qui envoie n'importe quel point M à un autre point N tel que le segment SN soit sur la même ligne que SM , mais mis à l'échelle par un facteur λ. En algèbre des ensembles, Scale est formulée comme suit :
Ainsi l'implémentation dans TypeScript est la suivante :
npm install
où (deltax, deltay) est le vecteur constant de la traduction et (lambdax, lambday) est le vecteur lambda.
Soit échelle la fonction qui applique une homothétie sur un ensemble du plan. Cette fonction est simplement implémentée comme suit dans TypeScript :
npm run numbers
l'échelle prend comme paramètres deltax qui est la distance delta dans la première dimension euclidienne, deltay qui est la distance delta dans la deuxième dimension euclidienne et (lambdax, lambday) qui est le vecteur facteur constant λ. Si un point P (x, y) est transformé par échelle dans un ensemble S, alors ses coordonnées changeront en (x', y') = (lambdax * x, delatx, lambday * y, deltay). Ainsi, le point ((x'- delatx)/lambdax, (y' - deltay)/lambday) appartiendra toujours à l'ensemble S, Si lambda est différent du vecteur 0, bien sûr. En algèbre des ensembles, l'échelle est appelée isomorphe, en d'autres termes, l'ensemble de toutes les homothéties forme le Groupe d'homothétie H, qui est isomorphe à l'espace lui-même {0}. Ceci explique la logique principale de la fonction.
Ainsi, exécutez le code ci-dessous dans notre page HTML5 :
npm run plane
donne le résultat suivant :
Soit rotatePoint la fonction qui fait pivoter un point avec un angle θ. En algèbre matricielle, rotatePoint est formulé comme suit :
où (x', y') sont les coordonnées du point après rotation, et la formule pour x' et y' est comme suit :
La démonstration de cette formule est très simple. Jetez un œil à cette rotation.
Ci-dessous la démonstration :
Ainsi l'implémentation dans TypeScript est la suivante :
npm install
Soit rotation la fonction qui applique une rotation sur un ensemble dans le plan d'angle θ. Cette fonction est simplement implémentée comme suit dans TypeScript.
npm run numbers
rotate est une fonction qui prend comme paramètre theta qui est l'angle de la rotation. Si un point P (x, y) est transformé par rotation dans un ensemble S, alors ses coordonnées changeront en (x', y') = (x * cos(theta) - y * sin(theta), x * sin(theta), y * cos(theta)). Ainsi, le point (x' * cos(theta), y' * sin(theta), y' * cos(theta) - x' * sin(theta)) appartiendra toujours à l'ensemble S. En algèbre des ensembles, la rotation est appelée isomorphe, en d'autres termes, l'ensemble de toutes les rotations forme le Groupe de rotation R, qui est isomorphe à l'espace lui-même. Ceci explique la logique principale de la fonction.
Ainsi, exécutez le code ci-dessous dans notre page HTML5 :
npm run plane
donne le résultat suivant :
Très simple, n'est-ce pas ? Pour ceux qui veulent aller plus loin, vous pouvez les explorer :
Les fractales sont des ensembles qui ont une dimension fractale qui dépasse généralement leur dimension topologique et peut se situer entre les nombres entiers. Par exemple, l'ensemble Mandelbrot est une fractale définie par une famille de polynômes quadratiques complexes :
npm run fractals
où c est un complexe. La fractale Mandelbrot est définie comme l'ensemble de tous les points c tels que la séquence ci-dessus ne s'échappe pas à l'infini. En algèbre des ensembles, cela se formule ainsi :
Les fractales (type de données abstrait) peuvent toujours être représentées comme suit dans TypeScript :
S'(x) = true if x is in S' S'(x) = false if x is not in S'
Afin de pouvoir dessiner des fractales, j'avais besoin de manipuler des nombres complexes. Ainsi, j'ai créé la classe Complex ci-dessous :
S'(a) = S'(b) = true S'(c) = S'(d) = false
J'ai créé une Fractale de Mandelbrot (représentation abstraite du type de données) P(z) = z^2 c qui est disponible ci-dessous.
npm installAfin de pouvoir dessiner des nombres _Complex_, j'ai créé une classe `ComplexPlane`. Vous trouverez ci-dessous l'implémentation dans TypeScript.
npm run numbers
Ainsi, exécutez le code ci-dessous :
npm run plane
où fractal est l'identifiant de la toile :
npm run fractals
donne le résultat suivant :
Pour ceux qui veulent aller plus loin, vous pouvez explorer ceux-ci :
C'est ça ! J'espère que vous avez apprécié la lecture.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!