J'ai commencé à écrire comme une explication supplémentaire de mon travail "Résumé de l'exécution d'une fonction récursive anonyme utilisant un combinateur de points immobile", pour décrire et utiliser la fonction curry. Il semblait qu'il serait utile pour au moins une personne (moi-même) d'en faire une feuille de triche indépendante, j'ai donc écrit un nouvel article. La définition de la fonction qui gère [pas **](#% E3% 82% AB% E3% 83% AA% E3% 83% BC% E5% 8C% 96% E3% 81% AE% Notez que E6% A6% 82% E8% A6% 81). En raison du fait qu'il couvre plusieurs langues, nous accueillons les personnes qui connaissent chaque langue et paradigme, y compris [Explication of curryization](#Overview of curryization).
La liste de notation uniquement est la suivante. f
est une fonction et ʻa` est un argument.
Langue | Changer les arguments | Spécification d'argument | Remarques |
---|---|---|---|
Haskell | Délimiteur vide | f a a ・ ・ ・ a |
|
Scheme | lambda Fonction anonyme par |
(・ ・ ・((f a) a)・ ・ ・a) |
|
Python | Fonction définie dans la fonction | f(a)(a)・ ・ ・(a) |
Des fonctions anonymes peuvent également être utilisées |
Ruby | -> Fonction anonyme utilisant |
f.(a).(a)・ ・ ・.(a) Ouf[a][a]・ ・ ・[a] |
Il existe une méthode au curry |
JavaScript | => Oufunction Fonction anonyme utilisant |
f(a)(a)・ ・ ・(a) |
|
Scala | => Fonction anonyme utilisant |
f(a)(a)・ ・ ・(a) |
Méthode Curly disponible, typée statiquement |
Perl | sub Sous-programme anonyme utilisant |
f(a)->(a)・ ・ ・->(a) |
$f->(a)・ ・ ・ Peut être |
Aller langue | func Fonction anonyme utilisant |
f(a)(a)・ ・ ・(a) |
Typage statique |
PHP | function Quanduse Fonction anonyme utilisant |
f(a)(a)・ ・ ・(a) |
7.À partir de 4fn Quand=> Fonction anonyme utilisant |
Standard ML | Délimiteur vide | f a a ・ ・ ・ a |
|
Julia | -> Fonction anonyme utilisant |
f(a)(a)・ ・ ・(a) |
|
Emacs Lisp | lambda Fonction anonyme par |
(funcall ・ ・ ・(funcall (f a) a)· · · UNE) |
24.Activer la portée lexicale après 1 |
Common Lisp | lambda Fonction anonyme par |
(funcall ・ ・ ・(funcall (f a) a)· · · UNE) |
|
Langue R | function Fonction anonyme par |
f(a)(a)・ ・ ・(a) |
Haskell(GHC)
Si vous spécifiez un argument séparé par des espaces sans utiliser (,)
lors de la définition d'une fonction, elle sera organisée. La spécification d'argument de la fonction de curling est «argument d'argument de fonction ・ ・ ・ argument».
Prelude> func (x,y,z) = if x > 0 then y else z
Prelude> func((-100),0,(-1))
-1
Prelude> func x y z = if x > 0 then y else z
Prelude> func (-100) 0 (-1)
-1
Scheme(Gauche)
Il est réalisé en utilisant une fonction anonyme utilisant lambda
comme valeur de retour. La spécification d'argument de la fonction de curling est (・ ・ ・ ((argument de fonction) argument) ・ ・ ・ argument)
. En fonction du système de traitement (comme Gauche), il est possible de définir une fonction (sans lambda
) selon le format lorsque l'argument est spécifié.
gosh> (define (func x y z) (if (> x 0) y z))
func
gosh> (func -100 0 -1)
-1
gosh> (define func (lambda (x) (lambda (y) (lambda (z) (if (> x 0) y z)))))
func
gosh> (((func -100) 0) -1)
-1
gosh> (define (((func x) y) z) (if (> x 0) y z))
func
gosh> (((func -100) 0) -1)
-1
Python(Python3,Python2)
Les fonctions anonymes utilisant lambda
peuvent être utilisées, mais comme il n'est pas recommandé pour PEP8 d'assigner directement une fonction anonyme à une variable, il est courant d'utiliser la fonction définie à l'intérieur de la fonction comme valeur de retour. .. La spécification d'argument de la fonction de curling est «fonction (argument) (argument) ... (argument)».
>>> def func(x, y, z): return y if x > 0 else z
...
>>> func(-100, 0, -1)
-1
>>> def func(x):
... def func(y):
... def func(z): return y if x > 0 else z
... return func
... return func
...
>>> func(-100)(0)(-1)
-1
>>> func = lambda x: lambda y: lambda z: y if x > 0 else z #PEP8 non recommandé
>>> func(-100)(0)(-1)
-1
Ruby(CRuby,JRuby)
En Ruby, une méthode curry «curry» est préparée. Cependant, une fonction anonyme multi-arguments est définie une fois par ->
puis curry
est appliqué. La spécification d'argument de la fonction de curling est fonction. (Argument). (Argument) ... (argument)
ou fonction [argument] [argument] ... [argument]
.
def func1(x,y,z) x > 0 ? y : z end
p func1(-100,0,-1) # => -1
func2 = -> x,y,z { x > 0 ? y : z }
p func2.curry.(-100).(0).(-1) # => -1
p func2.curry[-100][0][-1] # => -1
La méthode réalisée par une fonction anonyme utilisant uniquement ->
est la suivante.
func3 = -> x { -> y { -> z { x > 0 ? y : z } } }
p func3.(-100).(0).(-1) # => -1
p func3[-100][0][-1] # => -1
JavaScript(Node.js)
Il est réalisé par la méthode de retour d'une fonction anonyme en utilisant =>
ou function
. La spécification d'argument de la fonction de curling est «fonction (argument) (argument) ... (argument)».
function func1(x,y,z) { return x > 0 ? y : z }
console.log(func1(-100,0,-1)) // => -1
func2 = x => y => z => x > 0 ? y : z
console.log(func2(-100)(0)(-1)) // => -1
function func3(x) {
return function (y) {
return function (z) {
return x > 0 ? y : z
}
}
}
console.log(func3(-100)(0)(-1)) // => -1
Scala(Scala 2.11 + Java VM 12)
Scala propose une méthode de curry «curry». Cependant, une fonction anonyme multi-arguments est définie une fois par =>
puis curried
est appliqué. La spécification d'argument de la fonction de curling est «fonction (argument) (argument) ... (argument)».
scala> def func(x: Int, y: Int, z: Int): Int = if (x > 0) y else z
func: (x: Int, y: Int, z: Int)Int
scala> func(-100,0,-1)
res0: Int = -1
scala> val func = (x: Int, y: Int, z: Int) => if (x > 0) y else z
func: (Int, Int, Int) => Int = <function3>
scala> val func_curried = func.curried
func_curried: Int => (Int => (Int => Int)) = <function1>
scala> func_curried(-100)(0)(-1)
res1: Int = -1
La méthode réalisée par une fonction anonyme utilisant uniquement =>
est la suivante. Puisqu'il s'agit d'un langage à typage statique, il est nécessaire de clarifier la transition de type de la fonction entière.
scala> val func: Int => (Int => (Int => Int)) = (x: Int) => (y: Int) => (z: Int) => if (x > 0) y else z
func: Int => (Int => (Int => Int)) = <function1>
scala> func(-100)(0)(-1)
res2: Int = -1
Perl(perl 5)
Il est réalisé en utilisant une fonction anonyme (sous-section) utilisant sub
comme valeur de retour. La spécification d'argument de la fonction de curling est fonction (argument) -> (argument) ...-> (argument)
. Si le nom du corps de la fonction est également une fonction anonyme, c'est $ function-> (argument) -> (argument) ...-> (argument)
.
sub func { my ($x,$y,$z) = @_; $x > 0 ? $y : $z; };
print func(-100,0,-1), "\n"; # => -1
sub func_curried { my $x = shift; return sub { my $y = shift; return sub { my $z = shift; return $x > 0 ? $y : $z; }; }; };
print func_curried(-100)->(0)->(-1), "\n"; # => -1
my $func_curried2 = sub { my $x = shift; return sub { my $y = shift; return sub { my $z = shift; return $x > 0 ? $y : $z; }; }; };
print $func_curried2->(-100)->(0)->(-1), "\n"; # => -1
Il est réalisé en utilisant une fonction anonyme utilisant func
comme valeur de retour. La spécification d'argument de la fonction de curling est «fonction (argument) (argument) ... (argument)». Puisqu'il s'agit d'un langage de type statique, plus il gère d'arguments, plus il a de descriptions typées pour la valeur de retour de la fonction de chaque argument.
package main
import "fmt"
func func1 (x, y, z int) int { if x > 0 { return y } else { return z } }
func func2 (x int) func(int) func(int) int {
return func(y int) func(int) int {
return func(z int) int {
if x > 0 { return y } else { return z }
}
}
}
func main() {
fmt.Println(func1(-100,0,-1)) // => -1
fmt.Println(func2(-100)(0)(-1)) // => -1
}
PHP(PHP 7.3,PHP 7.4)
Jusqu'à PHP7.3, il est réalisé par la méthode de retour d'une fonction anonyme en utilisant function
et ʻuse`. La spécification d'argument de la fonction de curling est «fonction (argument) (argument) ... (argument)».
<?php
function func1($x,$y,$z) {
return ($x > 0) ? $y : $z;
}
echo func1(-100,0,-1) . PHP_EOL;
// => -1
function func2($x) {
return function($y) use ($x) {
return function($z) use ($x,$y) {
return ($x > 0) ? $y : $z;
};
};
}
echo func2(-100)(0)(-1) . PHP_EOL;
// => -1
Depuis PHP 7.4, les fonctions anonymes utilisant fn
et` => ʻ sont disponibles.
function func2($x) { return fn($y) => fn($z) => ($x > 0) ? $y : $z; }
echo func2(-100)(0)(-1) . PHP_EOL;
// => -1
Standard ML(SML/NJ)
Si vous spécifiez un argument séparé par des espaces sans utiliser (,)
lors de la définition d'une fonction, elle sera organisée. La spécification d'argument de la fonction de curling est «argument d'argument de fonction ・ ・ ・ argument».
- fun func (x, y, z) = if x > 0 then y else z;
val func = fn : int * 'a * 'a -> 'a
- func (~100, 0, ~1);
val it = ~1 : int
- fun func x y z = if x > 0 then y else z;
val func = fn : int -> 'a -> 'a -> 'a
- func ~100 0 ~1;
val it = ~1 : int
- func (~100)(0)(~1);
val it = ~1 : int
Julia(Version 1.0.5)
Il est réalisé en utilisant une fonction anonyme utilisant ->
comme valeur de retour. La spécification d'argument de la fonction de curling est «fonction (argument) (argument) ... (argument)».
julia> func1(x,y,z) = x > 0 ? y : z
func1 (generic function with 1 method)
julia> func1(-100,0,-1)
-1
julia> func2 = x -> y -> z -> x > 0 ? y : z
#3 (generic function with 1 method)
julia> func2(-100)(0)(-1)
-1
Si vous activez lexical-binding
(set t
avec setq
), vous serez en mode de portée lexicale, et vous pouvez utiliser des fermetures comprenant des expressions lambda
. La spécification d'argument pour le curry est (funcall ・ ・ ・ (funcall (argument de fonction) argument) ・ ・ ・ argument)
.
ELISP> (defun func (x y z) (if (> x 0) y z))
func
ELISP> (func -100 0 -1)
-1 (#o7777777777, #x3fffffff)
ELISP> (defun func (x) (lambda (y) (lambda (z) (if (> x 0) y z))))
func
ELISP> (funcall (funcall (func -100) 0) -1)
*** Eval error *** Symbol’s value as variable is void: x
ELISP> (setq lexical-binding t)
t
ELISP> (defun func (x) (lambda (y) (lambda (z) (if (> x 0) y z))))
func
ELISP> (funcall (funcall (func -100) 0) -1)
-1 (#o7777777777, #x3fffffff)
Common Lisp(SBCL 2.0.0)
Il est réalisé en utilisant une fonction anonyme utilisant lambda
comme valeur de retour. La spécification d'argument de la fonction de curling est (funcall ・ ・ ・ (funcall (argument de fonction) argument) ・ ・ ・ argument)
.
* (defun func (x y z) (if (> x 0) y z))
FUNC
* (func -100 0 -1)
-1
* (defun func (x) (lambda (y) (lambda (z) (if (> x 0) y z))))
FUNC
* (funcall (funcall (func -100) 0) -1)
-1
Il est réalisé en utilisant une fonction anonyme utilisant function
comme valeur de retour. La spécification d'argument de la fonction de curling est «fonction (argument) (argument) ... (argument)».
> func <- function(x,y,z) { if (x > 0) y else z }
> func(-100,0,-1)
[1] -1
> func <- function(x) { function(y) { function(z) { if (x > 0) y else z } } }
> func(-100)(0)(-1)
[1] -1
Curry est une [fonction d'ordre supérieur]( Spécifiez plusieurs arguments à l'aide de la fonction https://ja.wikipedia.org/wiki/%E9%AB%98%E9%9A%8E%E9%96%A2%E6%95%B0) Conversion d'une fonction en répétition d'une fonction qui ne spécifie qu'un seul argument. Il est connu comme un moyen d '"application partielle" qui permet le partage des descriptions de traitement, mais ce n'est qu'un des exemples d'utilisation. Les caractéristiques du curry lui-même sont qu'il est facile d'appliquer des théories mathématiques telles que le calcul lambda, de définir des fonctions à usage général qui reçoivent des arguments de manière récursive, d'ajuster l'application de valeurs pour chaque argument et de données. En recevant la structure élément par élément, une programmation plus concise et plus flexible devient possible.
En ce qui concerne les mérites du curry, les mots suivants dans cet article sont faciles à comprendre.
Dans curry, en plus de masquer $ x $ et de voir $ y $ comme une variable comme une application partielle, vous pouvez masquer $ y $ et voir $ x $ comme une variable.
Un exemple en Python serait:
>>> def func(x):
... def func(y): return (x - y)
... return func
...
>>> fx = func(5)
>>> [fx(y) for y in range(10)] #Valeur de x(5)Lorsque vous masquez et voyez y comme une variable (0-9)
[5, 4, 3, 2, 1, 0, -1, -2, -3, -4]
>>> fy = [func(x) for x in range(10)] #Valeur de y(5)Pour masquer et voir x comme une variable (0-9)
>>> [f(5) for f in fy]
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
En utilisant cette méthode de description, il est possible de curry facilement une fonction existante avec plusieurs arguments. Cependant, il n'est pas possible de créer une fonction ou une macro qui convertit une fonction existante avec plusieurs arguments en une fonction curry. La raison en est que le nombre d'arguments des fonctions existantes est indéfini et qu'il n'est pas possible de générer un nombre quelconque de fonctions anonymes et de fonctions internes (y compris la fonction de fermeture). Les méthodes Curry de Ruby et Scala sont converties à partir de fonctions anonymes avec plusieurs arguments définis individuellement.
Recommended Posts