Qual é a diferença entre currying e aplicação parcial da função na prática

8

Entendo a diferença entre aplicativo de função parcial e função com curry ( f(X x Y x Z) -> Nvs f(X -> (Y -> (Z -> N)))), mas não vejo qual é a conseqüência dessa diferença ao desenvolver software.

Henk
fonte

Respostas:

5

Originalmente, o curry era simplificar a análise, em vez de uma técnica de programação prática; no cálculo lambda, todas as funções são unárias. O curry é frequentemente usado no nível da linguagem por um motivo semelhante: simplificando o modelo computacional.

A aplicação parcial é usada quando uma função útil e nomeada pode ser implementada em termos de outra função mais geral, simplesmente fixando um argumento.

Eles permanecem formas distintas, envolvendo diferentes partes da computação. Considerar:

x=>y=>z=>f(x,y)
(y,z)=>f(0,y,z)

Observe que uma função ao curry não possui nenhum valor vinculado a argumentos e os leva em uma ordem específica; depois de curry uma função, você não curry o resultado e não altera a ordem em que a função recebe argumentos (embora você possa se apressar e curry para fazê-lo). Uma função parcial, ao contrário, tem valores vinculados a argumentos e pode ser aplicada parcialmente parcialmente ao longo de qualquer argumento restante.

A aplicação de uma função ao curry é quase uma aplicação parcial (afinal, você não modifica uma função e a deixa assim; em algum momento, você a aplicará), que é onde os usos começam a passar. Quando você faz isso, o curry é apenas o primeiro de dois passos para a aplicação parcial.

fora
fonte
2

Acredito que sua pergunta possa ser reformulada como: por que os idiomas têm currying?

É principalmente uma questão de conveniência:

No Ocaml, você poderia codificar

 let sum3 x y z = x + y + z;;
 let foo xx yy ll = List.map (sum3 xx yy) ll;;

No esquema, você precisará criar explicitamente uma função anônima

 (define (sum3 x y z) (+ x y z))
 (define (foo xx yy ll) (map (lambda (zz) (sum3 xx yy zz)) ll))  

Os idiomas com aplicativos parciais e curry precisam praticamente de uma otimização para evitar a criação de fechamentos parciais em todos os lugares; você não deseja que a implementação seja aplicada sempresum3 como se fosse definida como

 let sum3 x = 
    fun y -> 
      (fun z -> x + y + z)

isto é, alocar 2 fechamentos intermediários ao computar sum3 1 2 3(entendidos e analisados ​​como ((sum3 1) 2) 3...). Você deseja que a soma seja calculada imediatamente.

Basile Starynkevitch
fonte