[PYTHON] Curry Spickzettel

Als ich anfing, als ergänzende Erklärung meiner Arbeit "Zusammenfassung der Ausführung einer anonymen rekursiven Funktion mit dem Kombinator für unbewegliche Punkte" zu schreiben, um die Curry-Funktion zu beschreiben und zu verwenden Es schien für mindestens eine Person (mich) nützlich zu sein, den unabhängigen Spickzettel zu verwenden, also schrieb ich einen neuen Artikel. Die Definition der Funktion, die kuratiert [nicht **](#% E3% 82% AB% E3% 83% AA% E3% 83% BC% E5% 8C% 96% E3% 81% AE% Beachten Sie, dass E6% A6% 82% E8% A6% 81). Aufgrund der Tatsache, dass es mehrere Sprachen umfasst, begrüßen wir Personen, die mit jeder Sprache und jedem Paradigma vertraut sind, einschließlich [Erklärung der Curryisierung](#Übersicht über die Curryisierung).

Die Liste der Notation ist nur wie folgt. f ist eine Funktion und a ist ein Argument.

Sprache Argumente ändern Argumentspezifikation Bemerkungen
Haskell Leerzeichen f a a ・ ・ ・ a
Scheme lambdaAnonyme Funktion von (・ ・ ・((f a) a)・ ・ ・a)
Python In der Funktion definierte Funktion f(a)(a)・ ・ ・(a) Anonyme Funktionen können ebenfalls verwendet werden
Ruby ->Anonyme Funktion mit f.(a).(a)・ ・ ・.(a)Oderf[a][a]・ ・ ・[a] Es gibt eine Curry-Methode
JavaScript =>OderfunctionAnonyme Funktion mit f(a)(a)・ ・ ・(a)
Scala =>Anonyme Funktion mit f(a)(a)・ ・ ・(a) Curly-Methode verfügbar, statisch typisiert
Perl subAnonyme Unterroutine mit f(a)->(a)・ ・ ・->(a) $f->(a)・ ・ ・Vielleicht
Geh Sprache funcAnonyme Funktion mit f(a)(a)・ ・ ・(a) Statische Eingabe
PHP functionWannuseAnonyme Funktion mit f(a)(a)・ ・ ・(a) 7.Ab 4fnWann=>Anonyme Funktion mit
Standard ML Leerzeichen f a a ・ ・ ・ a
Julia ->Anonyme Funktion mit f(a)(a)・ ・ ・(a)
Emacs Lisp lambdaAnonyme Funktion von (funcall ・ ・ ・(funcall (f a) a)· · · EIN) 24.Aktivieren Sie den lexikalischen Bereich nach 1
Common Lisp lambdaAnonyme Funktion von (funcall ・ ・ ・(funcall (f a) a)· · · EIN)
R Sprache functionAnonyme Funktion von f(a)(a)・ ・ ・(a)

Haskell(GHC) Wenn Sie beim Definieren einer Funktion ein durch Leerzeichen getrenntes Argument angeben, ohne (,) zu verwenden, wird es kuratiert. Die Argumentspezifikation der Curling-Funktion lautet Funktionsargument Argument ・ ・ ・ 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) Dies wird durch Verwendung einer anonymen Funktion realisiert, die "Lambda" als Rückgabewert verwendet. Die Argumentspezifikation der Curling-Funktion lautet (・ ・ ・ ((Funktionsargument) Argument) ・ ・ ・ Argument). Abhängig vom Verarbeitungssystem (z. B. Gauche) ist es möglich, eine Funktion (ohne "Lambda") gemäß dem Format zu definieren, in dem das Argument angegeben wird.

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) Anonyme Funktionen, die Lambda verwenden, können verwendet werden. Da es für PEP8 jedoch nicht empfohlen wird, einer Variablen direkt eine anonyme Funktion zuzuweisen, wird häufig die in der Funktion definierte Funktion als Rückgabewert verwendet. .. Die Argumentspezifikation der Curling-Funktion lautet function (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 nicht empfohlen
>>> func(-100)(0)(-1)
-1

Ruby(CRuby,JRuby) In Ruby wird eine Curry-Methode "Curry" hergestellt. Eine anonyme Funktion mit mehreren Argumenten wird jedoch einmal durch "->" definiert, und dann wird "Curry" angewendet. Die Argumentspezifikation der Curry-Funktion lautet function. (Argument). (Argument) ・ ・ (. (Argument) oder function [argument] [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

Die Methode, die von einer anonymen Funktion nur mit -> realisiert wird, ist wie folgt.

func3 = -> x { ->  y { -> z { x > 0 ? y : z } } }
p func3.(-100).(0).(-1)          # => -1
p func3[-100][0][-1]             # => -1

JavaScript(Node.js) Dies wird durch die Methode der Rückgabe einer anonymen Funktion mit => oder function realisiert. Die Argumentspezifikation der Curling-Funktion lautet function (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 bietet eine Curry-Methode "Curry". Eine anonyme Funktion mit mehreren Argumenten wird jedoch einmal durch => definiert und dann wird curried angewendet. Die Argumentspezifikation der Curling-Funktion lautet function (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

Die Methode, die von einer anonymen Funktion nur mit => realisiert wird, ist wie folgt. Da es sich um eine statisch typisierte Sprache handelt, muss der Typübergang der gesamten Funktion geklärt werden.

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) Dies wird durch Verwendung einer anonymen Funktion (Unterabschnitt) unter Verwendung von "Unter" als Rückgabewert realisiert. Die Argumentspezifikation der Curling-Funktion lautet function (argument) -> (argument) ...-> (argument). Wenn der Name des Funktionskörpers auch eine anonyme Funktion ist, lautet er "$ 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

Gehe Sprache (gc)

Dies wird durch Verwendung einer anonymen Funktion realisiert, die "func" als Rückgabewert verwendet. Die Argumentspezifikation der Curling-Funktion lautet function (argument) (argument) ... (argument). Da es sich um eine statisch typisierte Sprache handelt, nimmt die typisierte Beschreibung für den Rückgabewert der Funktion jedes Arguments mit zunehmender Anzahl der behandelten Argumente zu.

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) Bis zu PHP7.3 wird dies durch die Methode realisiert, eine anonyme Funktion mit function und use zurückzugeben. Die Argumentspezifikation der Curling-Funktion lautet function (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

Ab PHP 7.4 stehen anonyme Funktionen mit fn und => zur Verfügung.

function func2($x) { return fn($y) => fn($z) =>  ($x > 0) ? $y : $z; }
echo func2(-100)(0)(-1) . PHP_EOL;
// => -1

Standard ML(SML/NJ) Wenn Sie beim Definieren einer Funktion ein durch Leerzeichen getrenntes Argument angeben, ohne (,) zu verwenden, wird es kuratiert. Die Argumentspezifikation der Curling-Funktion lautet Funktionsargument Argument ・ ・ ・ 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) Dies wird durch Verwendung einer anonymen Funktion realisiert, die -> als Rückgabewert verwendet. Die Argumentspezifikation der Curling-Funktion lautet function (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

Emacs Lisp (GNU Emacs 24.1 oder höher)

Wenn "lexikalische Bindung" aktiviert ist ("t" wird mit "setq" gesetzt), befindet es sich im lexikalischen Gültigkeitsbereich, und Abschlüsse mit "Lambda" -Ausdrücken sind verfügbar. Die Argumentspezifikation für Curry lautet (funcall ・ ・ ・ (Argument funcall (Funktionsargument)) ・ ・ ・ 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) Dies wird durch Verwendung einer anonymen Funktion realisiert, die "Lambda" als Rückgabewert verwendet. Die Argumentspezifikation der Curling-Funktion lautet (funcall ・ ・ ・ (Argument funcall (Funktionsargument)) ・ ・ ・ 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

R-Sprache (4.0.2)

Dies wird durch Verwendung einer anonymen Funktion realisiert, die function als Rückgabewert verwendet. Die Argumentspezifikation der Curling-Funktion lautet function (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

Bemerkungen

Übersicht über Curry

Curry ist eine [Funktion höherer Ordnung]( Geben Sie mehrere Argumente mit der Funktion https://ja.wikipedia.org/wiki/%E9%AB%98%E9%9A%8E%E9%96%A2%E6%95%B0 an. Es dient dazu, eine Funktion in eine Wiederholung einer Funktion umzuwandeln, die nur ein Argument angibt. Es ist als Mittel zur "Teilanwendung" bekannt, das das Teilen von Verarbeitungsbeschreibungen ermöglicht, aber es ist nur eines der Verwendungsbeispiele. Die Eigenschaften von Curry selbst sind, dass es einfach ist, mathematische Theorien wie die Lambda-Berechnung anzuwenden, Allzweckfunktionen zu definieren, die Argumente rekursiv empfangen, die Anwendung von Werten für jedes Argument anzupassen und Daten. Durch den elementweisen Empfang der Struktur wird eine präzisere und flexiblere Programmierung möglich.

In Bezug auf die Vorzüge von Curry sind die folgenden Wörter in diesem Artikel leicht zu verstehen.

In Curry können Sie nicht nur $ x $ ausblenden und $ y $ als Variable wie eine Teilanwendung anzeigen, sondern auch $ y $ ausblenden und $ x $ als Variable anzeigen.

Ein Beispiel in Python wäre:

>>> def func(x):
...     def func(y): return (x - y)
...     return func
... 
>>> fx = func(5)
>>> [fx(y) for y in range(10)]           #Wert von x(5)Beim Verstecken und Sehen von y als Variable (0-9)
[5, 4, 3, 2, 1, 0, -1, -2, -3, -4]
>>> fy = [func(x) for x in range(10)]    #Wert von y(5)X als Variable ausblenden und sehen (0-9)
>>> [f(5) for f in fy]
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]

Mit dieser Beschreibungsmethode ist es möglich, eine vorhandene Funktion mit mehreren Argumenten einfach zu curry. Es ist jedoch nicht möglich, eine Funktion oder ein Makro zu erstellen, die eine vorhandene Funktion mit mehreren Argumenten in eine Curry-Funktion konvertiert. Der Grund dafür ist, dass die Anzahl der Argumente vorhandener Funktionen unbestimmt ist und es nicht möglich ist, eine beliebige Anzahl anonymer Funktionen und interner Funktionen (einschließlich der Abschlussfunktion) zu generieren. Curry-Methoden in Ruby und Scala konvertieren aus anonymen Funktionen mit individuell definierten Mehrfachargumenten.

Ergänzende Informationen zum Artikel

Geschichte verändern

Recommended Posts

Curry Spickzettel
SQLite3 Spickzettel
pyenv Spickzettel
Curry-Spickzettel [Listenversion des Beschreibungsbeispiels]
PIL / Kissen Spickzettel
ps Befehl Spickzettel
Spark API Spickzettel
Python3 Spickzettel (Basic)
PySpark Cheet Sheet [Python]
Python-Spickzettel
Tox Einstellungsdatei Spickzettel
numpy Speicher wiederverwenden Spickzettel
[Python3] Standardeingabe [Cheet Sheet]
Data Science Cheet Sheet (Python)
Slack API Anhänge Spickzettel
Python Django Tutorial Cheet Sheet
Scikit lernen Algorithmus Spickzettel
Apache Beam Cheet Sheet [Python]
Persönlicher Spickzettel von Google Test / Mock
CPS-Spickzettel (Continuous Delivery Style)
Python-Spickzettel (für C ++ erfahren)
AtCoder Spickzettel in Python (für mich)
Blender Python Mesh Datenzugriffsprüfblatt
Cheet Sheet (Python) des Mathematical Optimization Modeler (PuLP)
OpenFOAM-Spickzettel für die Nachbearbeitung (von Zeit zu Zeit aktualisiert)
[Aktualisierung] Python Syntax Spickzettel für Java Shop
Tigerwicklung, die keinen Unfall verursacht
Cheet Sheet beim Schaben mit Google Colaboratory (Colab)