Je cherchais des exemples de technique de curry à Scala et je ne comprenais pas comment une fonction peut renvoyer une autre fonction lorsqu'une fonction est récursive.
Par exemple, je comprends ce code P>
def repeater(myFunc: Int => Int, n:Int): Int => Int = { if(n<=0) (x:Int) => x else (x: Int) => repeater(myFunc, n-1)(myFunc(x)) }
3 Réponses :
Déplaions la réursion étape par étape.
où où par conséquent et < Code> répéteur (addone, 2) code> renvoie une fonction anonyme qui ressemble à p> répéteur (addone, 2) code> retourne nouvelle fonction anonyme p>
répéteur (addone, 1) code> renvoie une nouvelle fonction anonyme p>
répéteur (addone, 0) code> retourne nouvelle fonction anonyme p >
répéteur (addone, 1) code> retourne une fonction anonyme qui ressemble à p>
Merci pour votre explication claire et brève. Penser avec Apply () La méthode est très utile et m'a fait comprendre plus facilement.
Bien sûr :) Mais je dois dire que trois de votre réponse sont bien expliquées et claires pour moi.
Pour le rendre plus compréhensible, je vais simplifier et descendre une partie de votre fonction.
Soit d'abord supprimer désinversoc fonctionne le code d'instanciation littéral p> alors vous pouvez donc voir que vous pouvez voir que Lorsque vous appelez ou le sucre le sucre p> alors vous avez donc maintenant que vous avez maintenant MyFunc CODE> PARAMETER et le remplacer par
Addone code> Fonction réduisant directement la complexité Garder la principale question dans la mise au point: p>
reporter (2) code> il produit une nouvelle fonction
# 2 code> sans l'évaluer. Donc, au résultat, vous aurez quelque chose comme ceci: p>
val code> contenant la fonction littéral que vous pouvez appeler comme ceci
répéteurfirsttraittration (...) code> p> p>
Merci, Lambda Expression comme (x: int) => x + 1 code> et crée fonction (instance de classe réellement) avec fonction1 est totalement identique à droite? (Comme dans Java et des interfaces fonctionnelles.) Autant que je sache, les fonctions Scala et Java sont presque identiques dans la création.
Oui. (x: int) => x + 1 code> est juste un sucre de syntaxe pour créer une instance de classe. Autant que je sache, Lambdas dans Java fonctionne de la même manière.
Tout d'abord, clarifions-nous si vous avez exécuté il pourrait ressembler un peu déroutant mais permet de le casser. p> permet de se concentrer sur la partie la plus interne - permet de regarder le Nous pouvons appliquer la même logique utilisée à l'étape précédente pour casser le donc pour et tout ça répéteur (addone, 3) code>, vous ne récupérerez qu'une fonction. Vous auriez besoin d'exécuter
répéteur (addone, 3) (quelque purée) code> pour obtenir votre valeur entière et le résultat de votre calcul. Tout ce que la récursion fait ici consiste à construire une fonction.
répéteur (addone, 3) code> renvoie une fonction qui prend un entier et retourne un entier. Prenez l'exemple de
répéteur (addone, 3) code>, si nous écrivons le résultat de la récursion complète, c'est ce que nous obtenons
{x => x} (myfunc (x)) code>. Cela peut être séparé en deux parties, une fonction et une entrée à la fonction. La fonction est
{x => x} code> et l'entrée de cette fonction est
(myfunc (x)) code>. Dans ce cas, tout ce que la fonction est renvoyée à l'utilisateur. Ainsi, si nous écrivons
{x => x} (1) code> nous obtiendrons
1 code>. Nous pouvons donc remplacer l'ensemble du
{x => x} (myfunc (x)) code> avec juste
myfunc (x) code>. Ce qui nous reste, c'est p>
{x => myfunc (x)} (myfunc (x)) code> terme. Ici, la partie de fonction est
{x => myfunc (x)} code> et l'entrée de cette partie de fonction est donnée par
(myfunc (x)) code>. La partie de fonction prend dans un entier
x code> et applique
myfunc code> à cet entiteur. C'est essentiellement la même chose que l'application
myfunc code> directement sur cet entier. Dans ce cas, l'entier que nous l'appliquons est l'entrée
myfunc (x) code> afin que nous puissions réécrire
{x => myfunc (x)} (myfunc (x)) code > comme
myfunc (myfunc (x)) code>. Maintenant, nous avons p>
{x => myfunc (myfunc (x))} (myfunc (x))) code> terme. Nous obtiendrions
myfunc (myfunc (myfunc (x))) code>. Si vous continuez avec cette logique, vous verrez que
répéteur code> va continuer à composer
myfunc code>. Pour chaque
n code>, il ajoutera une couche supplémentaire de
myfunc code>. Le résultat de cela ressemblerait à ceci si
n = 3 code> p>
répéteur (addone, 3) code>, nous obtiendions p>
répéteur (addone, 5) code> est p>
Répéteur Code> Cela construit-il simplement cette fonction et le renvoie à l'utilisateur. Vous pouvez prendre cette fonction de retour de
répéteur code> et mettre dans un
val code> appelé
f code> p>
f code> prend une entrée entière et renvoie qu'Eteger Plus 3. Nous pouvons alors obtenir le résultat réel que nous voulons utiliser ce P>
val someIntegerPlus3: Int = f(someInteger)