I informatikk , nærmere bestemt i funksjonell programmering , er karriing transformasjon av en funksjon med flere argumenter til en funksjon med ett argument som returnerer en funksjon på resten av argumentene. Den omvendte operasjonen er mulig og kalles avrensing .
Begrepet kommer fra navnet på den amerikanske matematikeren Haskell Curry , selv om denne operasjonen først ble introdusert av Moses Schönfinkel .
Tenk på en funksjon addsom tar to argumenter ( x og y ) og returnerer summen av dem. Ved å curry det får vi en funksjon addcursom tar ett argument og returnerer en funksjon som tar det andre argumentet. På pseudospråk:
curry (add (x,y)) → addcur x → lambda (y → x + y)Den currying tillater den delvise anvendelse hvis kalt curried funksjon med argument 3, gjenvinning av en funksjon som legger 3 til dens argument.
I Haskell er her en ikke-karri-funksjon:
uncurried_add (x, y) = x + yog det samme etter karri :
curried_add x y = x + yeller:
curried_add x = \y -> x + yder skråstrek \ introduserer et λ-uttrykk (lambda-uttrykk) og brukes til å definere anonyme funksjoner. Og her er en delvis søknad:
main = do print (uncurried_add (3, 5)) -- 8 print ((curried_add 3) 5) -- 8 print (curried_add 3 5) -- 8 let add_three = curried_add 3 print (add_three 5) -- 8 print (add_three 12) -- 15 MerknaderDen currying kan gjøres manuelt eller ved et program. For funksjoner med to argumenter, her er disse programmene i Haskell:
main = do let uncurried = uncurry curried_add print (uncurried (3, 5)) -- 8 let curried = curry uncurried_add print ((curried 3) 5) -- 8 print (curried 3 5) -- 8 let add_three = curried 3 print (add_three 5) -- 8 print (add_three 12) -- 15Samme funksjon i Python :
def uncurried_add(x, y): return x + y def curried_add(x): return lambda y: x + y print(uncurried_add(3, 5)) # 8 print(curried_add(3)(5)) # 8 add_three = curried_add(3) print(add_three(5)) # 8 print(add_three(12)) # 15Samme funksjon i Caml :
let uncurried_add(x, y) = x + y;; (* Type de la fonction : (entier * entier) -> entier *) let curried_add x y = x + y;; (* Type de la fonction : entier -> entier -> entier *) uncurried_add(3,4);; (* Retourne 7. Type de la valeur retournée : entier. *) curried_add 3;; (* Retourne la fonction qui ajoute 3. Type de la valeur retournée : entier -> entier. *) (curried_add 3) 4;; (* Crée la fonction qui ajoute 3 et l'applique à l'entier 4. Retourne 7. Type de la valeur retournée : entier. *) let add_three = curried_add 3;; (* Définit la fonction add_three comme la fonction qui ajoute 3 à son argument. *) add_three 5;; (* Applique add_three à 5. Retourne 8. *) add_three 12;; (* Applique add_three à 12. Retourne 15. *)Ruby gir lambda-uttrykket karri-metoden. Metoden tar som argument et valgfritt argument: arity, som tillater finere prosesser, som ikke vil bli diskutert her.
uncurried_add = lambda { |x, y| x + y } puts uncurried_add.call(3, 5) # 8 puts uncurried_add.curry[3][5] # 8 add_three = uncurried_add.curry[3] puts add_three.call(5) # 8 puts add_three.call(12) # 15EN JAPH som er et eksempel på karri i Perl 6 :
sub japh (Str $lang) { say "just another $lang hacker"; } my &perl6Japh := &japh.assuming("Perl6"); perl6Japh();C ++ 11 introduserte lambdas til språket, og deretter C ++ 14 introduserte muligheten til å definere en automatisk returtype for å gjøre det lettere å skrive visse funksjoner.
Disse to forbedringene gjør det mulig å implementere karri:
#include <iostream> int uncurried_add(int x, int y) { return x + y; } auto curried_add(int x) { return [x](int y) { return x + y; }; } int main() { std::cout << uncurried_add(3, 5) << std::endl; // 8 std::cout << curried_add(3)(5) << std::endl; // 8 auto add_three = curried_add(3); std::cout << add_three(5) << std::endl; // 8 std::cout << add_three(12) << std::endl; // 15 }Merk at siden C ++ 17 kan nevnelsen av typen int i argumentet for lambdauttrykket også erstattes av auto , og generaliserer implementeringen (på bekostning av å gjøre curried_add- metoden til en implisitt mal).
“ På den siste linjen har vi brukt et triks kalt Currying (etter logikeren H. Curry) for å løse problemet med å introdusere en binær operasjon til et språk der alle funksjoner må akseptere et enkelt argument. (Dommeren kommenterer at selv om "Currying" er bedre, kan "Schönfinkeling" være mer nøyaktig.) »