Maison > interface Web > js tutoriel > le corps du texte

Implémentation de Curry dans la programmation fonctionnelle JavaScript

黄舟
Libérer: 2017-03-02 14:53:09
original
1343 Les gens l'ont consulté

Récemment j'apprends la programmation fonctionnelle JavaScript, et je suis très intéressé par le fameux curry La fonction curry peut accepter une fonction, appelons-la la fonction originale pour le moment, et elle renvoie un. fonction, curry.Fonction, la fonction curry renvoyée est très puissante. Pendant le processus d'exécution, elle renvoie en continu une fonction qui stocke les paramètres transmis jusqu'à ce que les conditions d'exécution de la fonction d'origine soient déclenchées. C'est plus général, donnons donc un exemple pour illustrer :

Fonction originale :

var add = (x, y) => x + y
Copier après la connexion

Fonction Curry :

 var curryAdd = curry(add)
Copier après la connexion

Cet ajout nécessite deux paramètres, mais notre exécution curryAdd peut transmettre moins de paramètres. Lorsque les paramètres transmis sont inférieurs aux paramètres requis par add, la fonction add ne sera pas exécutée. écrira ce paramètre et en renverra une autre. les paramètres entrants. Nous aurons une variable pour enregistrer les paramètres entrants. Si le nombre total de paramètres entrants est égal au nombre total de paramètres requis par l'ajout, nous activerons l'exécution du paramètre d'origine et il retournera ce que nous voulons. résultat.

// 此时只传入了一个参数 根据判断返回的是一个函数
    var add2 = curryAdd(2)
    // add2 = function(...) {}
Copier après la connexion
// 此时累计传入了两个参数 等于了add需要参数的总和 所以返回的是一个结果
    // 相当于执行了add(2)(3)
    var result = add2(3)
    // result = 5
Copier après la connexion

C'est plutôt bien, non ? Eh bien, notre objectif est d'écrire cette fonction magique du curry, et nous devons l'écrire sur une seule ligne, analysons comment l'écrire. d'abord, puis optimisez étape par étape.

D'après la description ci-dessus, jetons un coup d'œil à ce dont la fonction curry a besoin. Tout d'abord, nous avons besoin d'une variable pour stocker le nombre de paramètres de la fonction d'origine. Nous savons que cette fonction a un attribut appelé longueur, et c'est tout. Nous utilisons la limite pour le sauvegarder

    var curry = function(fn) {
         var limit = fn.length
         ...
    }
Copier après la connexion

La fonction curry doit renvoyer une fonction, et cette fonction doit être exécutée. La question est, nous devons déterminer si l'exécution de cette fonction s'active. l'exécution de la fonction d'origine. Le problème se pose au-dessus des paramètres transmis. Fonction de retour ou résultat ? C'est en effet un problème. Écrivons d'abord le résultat renvoyé lorsque les paramètres transmis sont égaux aux paramètres requis par la fonction d'origine, nous exécutons la fonction d'origine fn

    var curry = function(fn) {
         var limit = fn.length
         return function (...args) {
             if (args.length >= limit) {
                 return fn.apply(null, args)
             }
         }
    }
Copier après la connexion

, sinon nous renverrons un. stockage Il y a deux points ici pour la fonction des paramètres. L'un est que nous devons enregistrer l'historique des paramètres transmis. L'autre est ce que la fonction renvoyée doit faire

    var curry = function(fn) {
         var limit = fn.length
         return function (...args) {
             if (args.length >= limit) {
                 return fn.apply(null, args)
             } else {
                 return function(...args2) {

                 }
             }
         }
    }
Copier après la connexion

Voir. Nous avons seulement besoin de renvoyer la fonction. L'accumulation des paramètres exécutés atteint l'objectif d'enregistrer les paramètres transmis, nous avons donc pensé à concat en args.concat(args2), et ainsi de suite. Ce que la fonction que nous retournons doit faire, c'est répéter. les choses ci-dessus, c'est-à-dire que les paramètres sont La fonction de args doit faire quelque chose, elle a donc besoin d'un nom, sinon nous ne pouvons pas l'exécuter, nous l'appelons JudgeCurry

Donc, comme nous l'avons dit, soit return une fonction ou exécuter la fonction d'origine.

    var curry = function(fn) {
         var limit = fn.length
         return function judgeCurry (...args) {
             if (args.length >= limit) {
                 return fn.apply(null, args)
             } else {
                 return function(...args2) {
                     return judgeCurry.apply(null, args.concat(args2))                                     
                 }
             }
         }
    }
Copier après la connexion

Nous avons enfin fini d'écrire cette fonction magique de curry. Elle est vraiment puissante lorsqu'elle est combinée avec la composition, c'est vraiment cool.

Notre objectif est d'écrire la fonction ci-dessus sur une seule ligne, une seule ligne ? Comment écrire ? Au fait, j'utilise ES6, donc j'ai passé beaucoup de temps

var currySingle = fn => judgeCurry = (...args) => args.length >= fn.length ? fn.apply(null, args) : 
(...args2) => judgeCurry.apply(null, args.concat(args2))
Copier après la connexion

D'accord, voyons quel est le problème. Au fait, pour ne pas utiliser le paramètre limit, il faut attribuer. une valeur lors de son utilisation. L'affectation ne peut pas être effectuée sur une seule ligne, cela deviendra comme ceci

    var currySingle = fn => {
        var limit = fn.length
        var judgeCurry = null
        return judgeCurry = (...args) => args.length >= limit ? fn.apply(null, args) : (...args2) => judgeCurry.apply(null, args.concat(args2))
    }
Copier après la connexion

Lorsque vous aurez besoin de juger les paramètres, fn.length est constamment évalué, mais la valeur de fn. .length est certain. Nous ne voulons pas l'évaluer à chaque fois, mais que dois-je faire si je ne veux pas utiliser de limite ? Vous avez dû penser à exécuter la fonction immédiatement ! !

var currySingle = fn => ((limit) => judgeCurry = (...args) => args.length >= limit ? fn.apply(null, args) : 
(...args2) => judgeCurry.apply(null, args.concat(args2)))(fn.length)
Copier après la connexion

Je dois soupirer devant la magie du javascript Enfin, nous avons écrit ce curry magique en une seule ligne.

Ce qui précède est le contenu de l'implémentation de curry dans la programmation fonctionnelle JavaScript. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (m.sbmmt.com) !

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!