2010-09-02 15 views
7

estoy leyendo acelerada C# No entiendo muy bien el siguiente código:necesita ayuda para entender lambda (currificación)

public static Func<TArg1, TResult> Bind2nd<TArg1, TArg2, TResult> (
    this Func<TArg1, TArg2, TResult> func, 
    TArg2 constant) 
{ 
    return (x) => func(x, constant); 
} 

en la última línea de lo que se refería a x? y hay otra:

public static Func<TArg2, Func<TArg1, TResult>> Bind2nd<TArg1, TArg2, TResult> 
(this Func<TArg1, TArg2, TResult> func) 
{ 
    return (y) => (x) => func(x, y); 
} 

¿Cómo puedo evaluar esto? (y) => (x) => func(x, y) qué pasa donde ... confunde.

Respuesta

19

primero vamos a simplificar el código:

Func<int, int> B(Func<int, int, int> f, int c) 
{ 
    return x=>f(x, c); 
} 

Esto es lo mismo que:

class Locals 
{ 
    public int c; 
    public Func<int, int, int> f; 
    public int Magic(int x) { return f(x, c); } 
} 
Func<int, int> B(Func<int, int, int> f, int c) 
{ 
    Locals locals = new Locals(); 
    locals.f = f; 
    locals.c = c; 
    return locals.Magic; 
} 

Ahora es claro a que se refiere x? x es el parámetro para funcionar "Magia".

Ahora puede utilizar B como esto:

Func<int, int, int> adder = (a, b)=>a+b; 
Func<int, int> addTen = B(adder, 10); 
int thirty = addTen(20); 

sentido? ¿Ves lo que está pasando aquí? Estamos tomando una función de dos parámetros y "fijando" uno de los parámetros a una constante. Entonces se convierte en una función de un parámetro.

El segundo ejemplo lo lleva un paso más allá. Una vez más, simplificar para deshacerse de la costra de manera que se puede entender más fácilmente:

Func<int, Func<int, int>> B2(Func<int, int, int> f) 
{ 
    return y=>x=>f(x,y); 
} 

Esto es lo mismo que

class Locals3 
{ 
    public int y; 
    public int Magic3(int x) 
    { 
     return x + this.y; 
    } 
} 
class Locals2 
{ 
    public Func<int, int, int> f; 
    public Func<int, int> Magic2(int y) 
    { 
     Locals3 locals = new Locals3; 
     locals.y = y; 
     return locals.Magic3; 
    } 
} 

Func<int, Func<int, int>> B2(Func<int, int, int> f) 
{ 
    Locals2 locals = new Locals2(); 
    locals.f = f; 
    return locals.Magic2; 
} 

Así que decir

Func<int, int, int> adder = (a, b)=>a+b; 
Func<int, Func<int, int>> makeFixedAdder = B2(adder); 
Func<int, int> add10 = makeFixedAdder(10); 
int thirty = add10(20); 

B es una fijador de parámetros. B2 hace un fijador de parámetros para usted.

Sin embargo, ese no es el punto de B2. El punto de B2 es que:

adder(20, 10); 

da el mismo resultado que

B2(adder)(20)(10) 

B2 resulta una función de dos parámetros en dos funciones de un parámetro de cada.

¿Tiene sentido?

+0

Debo decir gracias por su explicación detallada. Ahora incluso lo entiendo :) – Riaan

1

x es el parámetro de la lambda, es del tipo TArg1.

Puede ser útil pronunciar el => como "mapas a" como en "x correlaciones a una nueva función con una constante de tipo TArg2 sustituida en la función original delegado, func".

+0

Solo un agregado, MSDN dice read '=>' as * goes to *. –

1

La variable x es una variable independiente. Eso representa un argumento para la función devuelta al llamar al Bind2nd.

Algunas horas con Scheme podrían ayudarlo aquí, pero intente esto.

Cuando llama al Bind2nd, el resultado devuelto es una función. Esa función se define como

(x) => func (x, constant) 

Ahora que ha lo anterior asignado a una variable, digamos lambda, puede llamar a esa función a través de la lambda variables

lambda(x); 

El x se define en Bind2nd es sólo una variable que representa un argumento para la función que se le devolverá.

1

Una expresión lambda es la abreviatura de método anónimo. Al igual que el método anónimo, la expresión lambda se asigna para delegar tipos. Todas las condiciones que se aplican a los métodos anónimos también se aplican a las expresiones lambda.

=> se llama operador lambda, que se lee como "goes to". El lado izquierdo del operador especifica los parámetros de entrada separados por coma, y ​​el lado derecho especifica un bloque de expresión o declaración que se llama cuerpo lambda. (p1, p2, p3, ... pN) => expresión Si solo tiene un parámetro, puede omitir el paréntesis p1 => expresión;

he escrito un pequeño blog que explica la expresión lambda aquí Lambda Expression

Cuestiones relacionadas