Delvis tillämpning
Inom datavetenskap hänvisar partiell tillämpning (eller partiell funktionsapplikation ) till processen att fixa ett antal argument till en funktion, vilket skapar en annan funktion med mindre aritet . Givet en funktion kan vi fixa (eller 'binda') det första argumentet och skapa en funktion av typen . Utvärdering av denna funktion kan representeras som . Observera att resultatet av partiell funktionstillämpning i detta fall är en funktion som tar två argument. Partiell applicering kallas ibland felaktigt för currying , vilket är ett besläktat, men distinkt koncept.
Motivering
Intuitivt säger partiell funktionsapplikation "om du fixar de första argumenten för funktionen får du en funktion av de återstående argumenten". Till exempel, om funktionen div ( x , y ) = x / y , så är div med parametern x fixerad till 1 en annan funktion: div 1 ( y ) = div (1, y ) = 1/ y . Detta är samma sak som funktionen inv som returnerar den multiplikativa inversen av dess argument, definierad av inv ( y ) = 1/ y .
Den praktiska motiveringen för partiell tillämpning är att de funktioner som erhålls genom att tillhandahålla några men inte alla argument till en funktion väldigt ofta är användbara; till exempel har många språk en funktion eller operator som liknar plus_one
. Partiell applikation gör det enkelt att definiera dessa funktioner, till exempel genom att skapa en funktion som representerar additionsoperatorn med 1 bundet som sitt första argument.
Genomföranden
I språk som ML , Haskell och F# , definieras funktioner som standard i curryform . Att tillhandahålla färre än det totala antalet argument kallas partiell tillämpning.
I språk med förstklassiga funktioner kan man definiera curry
, uncurry
och papply
för att explicit utföra currying och partiell tillämpning. Detta kan medföra större driftskostnader på grund av skapandet av ytterligare stängningar , medan Haskell kan använda mer effektiva tekniker.
Scala implementerar valfri partiell applikation med platshållare, t.ex. def add ( x : Int , y : Int ) = { x + y }; add ( 1 , _: Int )
returnerar en inkrementerande funktion. Scala stöder även flera parameterlistor som currying, t.ex. def add ( x : Int )( y : Int ) = { x + y }; lägg till ( 1 ) _
.
Clojure implementerar partiell applikation med hjälp av den partiella
funktionen som definieras i dess kärnbibliotek.
C ++ -standardbiblioteket tillhandahåller bind(function, args..)
för att returnera ett funktionsobjekt som är resultatet av en partiell tillämpning av de givna argumenten på den givna funktionen. Alternativt lambda-uttryck användas:
int f ( int a , int b ); auto f_partial = []( int a ) { return f ( a , 123 ); }; hävda ( f_partial ( 456 ) == f ( 456 , 123 ) );
I Java tillämpar MethodHandle.bindTo delvis en funktion på dess första argument
. Alternativt, sedan Java 8, kan lambdas användas:
public static < A , B , R > Funktion < B , R > partiell Tillämpa ( BiFunction < A , B , R > biFunc , A värde ) { return b -> biFunc . tillämpa ( värde , b ); }
I Raku skapar antagandemetoden en ny funktion med färre parametrar .
Python - standardbiblioteksmodulens funktionsverktyg
inkluderar den partiella
funktionen, som tillåter positionella och namngivna argumentbindningar, vilket returnerar en ny funktion.
I XQuery används en argumentplatshållare ( ?
) för varje icke-fixerat argument i en delfunktionsapplikation.
Definitioner
I den enkelt skrivna lambdakalkylen med funktion och produkttyper ( λ →,× ) partiell applicering kan currying och uncurrying definieras som
papply
- ((( a × b ) → c ) × a ) → ( b → c ) = λ ( f , x ). λy . f ( x , y )
curry
- (( a × b ) → c ) → ( a → ( b → c )) = λf . λx . λy . f ( x , y )
uncurry
- ( a → ( b → c )) → (( a × b ) → c ) = λf . X ( x , y ). fxy
Observera att curry
papply
= curry
.
Matematisk formulering och exempel
Partiell tillämpning kan vara ett användbart sätt att definiera flera användbara begrepp inom matematik.
Givet uppsättningar och och en funktion , kan man definiera funktionen
där är uppsättningen funktioner . Bilden av under denna karta är . Detta är funktionen som skickar till . Det finns ofta strukturer på som innebär att bilden av begränsar sig till någon delmängd av funktioner , som illustreras i följande exempel.
Gruppåtgärder
En gruppåtgärd kan förstås som en funktion . Den partiella utvärderingen begränsar till gruppen av bijektioner från till sig själv. Axiomen för grupphandling säkerställer vidare är en grupphomomorfism .
Inre-produkter och kanonisk karta till dual
En inre produkt på ett vektorrum över ett fält är en karta . Den partiella utvärderingen ger en kanonisk karta till det dubbla vektorrummet , . Om detta är den inre produkten av ett Hilbert-rum , säkerställer Riesz-representationssatsen att detta är en isomorfism .
Korsprodukter och den angränsande kartan för Lie-algebror
Den partiella tillämpningen av korsprodukten på är . Bilden av vektorn är en linjär karta så att . Komponenterna i kan ses vara .
Detta är nära besläktat med den angränsande kartan för Lie algebras . Liealgebror är utrustade med en parentes . Den partiella applikationen ger en kartannons . Axiomen för parentesen säkerställer att denna karta är en homomorfism av Lie-algebra.
Se även
- η-omvandling
- POP-2
- Restriktion (matematik) , det mer allmänna fenomenet att begränsa en funktion till en delmängd av dess domän
Vidare läsning
- Marlow, Simon ; Peyton Jones, Simon (2004), "Making a Fast Curry: Push/Enter vs. Eval/Apply for Higher-order Languages" , ICFP '04 Proceedings of the nionth ACM SIGPLAN internationella konferens om funktionell programmering
- Benjamin C. Pierce et al. "Partial Application" , Arkiverad 2016-05-21 på Wayback Machine "Digression: Currying" . Arkiverad 2016-05-21 på Wayback Machine Software Foundations .
externa länkar
- Delfunktionsapplikation på Rosetta-kod.
- Delansökan på Haskell Wiki
- Konstant ansökningsformulär på Haskell Wiki
- Farorna med att vara för partisk