Нужна помощь в понимании лямбда (карри) - PullRequest
7 голосов
/ 02 сентября 2010

Я читаю Ускоренный C # Я не совсем понимаю следующий код:

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

в последней строке, что означает х? и есть другое:

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

Как мне это оценить? (y) => (x) => func( x, y ) что передается, где ... это сбивает с толку.

Ответы [ 4 ]

19 голосов
/ 02 сентября 2010

Давайте сначала упростим код:

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

Это так же, как:

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;
}

Теперь понятно, к чему относится х? х - параметр для функции «Магия».

Теперь вы можете использовать B следующим образом:

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

Имеет смысл? Видишь, что здесь происходит? Мы берем функцию двух параметров и «фиксируем» один из параметров на постоянном. Таким образом, он становится функцией одного параметра.

Второй пример делает этот шаг еще дальше. Опять же, упростите избавление от промаха, чтобы вам было легче его понять:

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

Это то же самое, что и

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;
}

Так вы говорите

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 - фиксатор параметров. B2 делает для вас фиксатор параметров .

Однако это не точка в B2. Дело в том, что B2:

adder(20, 10);

дает тот же результат, что и

B2(adder)(20)(10)

B2 превращает одну функцию из двух параметров в две функции по одному параметру каждый .

Имеет смысл?

1 голос
/ 02 сентября 2010

Переменная x является несвязанной переменной. Это представляет аргумент возвращаемой функции от вызова Bind2nd.

Несколько часов со Схемой помогут вам здесь, но попробуйте это.

Когда вы вызываете Bind2nd, возвращаемый результат является функцией. Эта функция определяется как

(x) => func (x, constant)

Теперь, когда у вас есть вышеуказанное значение для переменной, скажем, lambda, вы можете вызвать эту функцию через lambda переменную

lambda(x);

x, определенный в Bind2nd - это просто переменная, представляющая аргумент функции, которая будет вам возвращена.

1 голос
/ 02 сентября 2010

Лямбда-выражение является сокращением для анонимного метода. Как и анонимный метод, лямбда-выражение присваивается типам делегатов. Все условия, применимые к анонимным методам, также применяются к лямбда-выражениям.

=> называется лямбда-оператором, который читается как «идет». Левая часть оператора задает входные параметры, разделенные запятой, а правая часть определяет блок выражения или оператора, который называется лямбда-телом. (p1, p2, p3,… pN) => выражение Если у вас есть только один параметр, вы можете пропустить выражение p1 => в скобках;

Я написал небольшой блог, объясняющий лямбда-выражение здесь Лямбда-выражение

1 голос
/ 02 сентября 2010

x - это параметр лямбды, он имеет тип TArg1.

Может быть полезно произнести => как «сопоставляется» с тем, как в «x отображает новую функцию с константой типа TArg2, подставленной в исходный делегат функции func.»

...