Лямбда возвращает другую лямбду.

есть ли способ рекурсивно вернуть лямбду из другой лямбды?

все, что я хочу сделать, это конечный автомат, реализованный как лямбда, который возвращает лямбда, реализующий другое состояние (или null).

вложенность Func не будет работать так, как я хочу.

в C#, .Net 3.5 с

пример:

машина, 3 состояния, псевдоязык

private Lambda State1()
{  
    if (SomeConditionIsMet)
        return State2;
    else
        return State1;
}

private Lambda State2()
{  
    while (SomeConditionIsMet)
        return State2;
    else
        return State3;
}

private Lambda State3()
{  
    LogEnd();
    return NULL;
}

public void FSM()
{
    Lambda _currentState = State1;

    while(_currentState != NULL)
    {
        _currentState = _currentState();
    }
}

Я знаю, что могу обойти это с помощью enum+switch, например, но я просто любопытно, смогу ли я это сделать.

4 ответов


Я верю, что вы можете объявить тип делегата: public delegate Lambda Lambda() который возвращает делегат собственного типа. Во всяком случае, он компилируется.


конечно, вы можете вернуть лямбду от другой лямбды:

Func<int, Func<int, int>> makeAdder = x => y => x + y;
Func<int, int> addTen = makeAdder(10);
Console.WriteLine(addTen(20)); // 30

С каким аспектом синтаксиса у вас возникли проблемы? Мне интересно знать, как люди ошибаются, потому что это помогает нам лучше разрабатывать язык и документацию в следующий раз.

обновление:

Ну, но вы не можете вернуть лямбда возвращение лямбда

конечно, вы можете.

Func<int, Func<int, int>> GetAdderMaker()
{
    return x => y => x + y;
}

вот мы возвращаем лямбда, что возвращает лямбду. Почему вы считаете, что это невозможно?

обновление:


на ваш вопрос уже дан ответ, но тем, кто читает это, может быть интересно отметить, что вы можете использовать этот метод для внедрения лямбда-исчисления в C#.

во-первых, начиная с:

    public delegate Lambda Lambda(Lambda x);

используя различные определения функций, найденные в http://en.wikipedia.org/wiki/Lambda_calculus я определил различные примитивы следующим образом:

    public static Lambda Id         = x => x;
    public static Lambda Zero       = f => x => x;
    public static Lambda True       = x => y => x;
    public static Lambda False      = x => y => y;
    public static Lambda One        = f => x => f(x);
    public static Lambda Two        = f => x => f(f(x));
    public static Lambda Succ       = n => f => x => f(n(f)(x));
    public static Lambda Three      = Succ(Two);
    public static Lambda Pred       = n => f => x => n(g => h => h(g(f)))(u => x)(Id);
    public static Lambda Plus       = m => n => f => x => m(f)(n(f)(x));
    public static Lambda Sub        = m => n => n (Pred) (m);
    public static Lambda And        = p => q => p(q)(p);
    public static Lambda Or         = p => q => p(p)(q);
    public static Lambda Not        = p => a => b => p(b)(a);
    public static Lambda IfThenElse = p => a => b => p(a)(b);
    public static Lambda IsZero     = n => n(x => False)(True);
    public static Lambda IsLtEqOne  = n => IsZero(Pred(n));
    public static Lambda Pair       = x => y => f => f(x)(y);
    public static Lambda First      = pair => pair(True);
    public static Lambda Second     = pair => pair(False);
    public static Lambda Nil        = x => True;
    public static Lambda Null       = p => p(x => y => False);
    public static Lambda LtEq       = x => y => IsZero(Sub(x)(y));
    public static Lambda Gt         = x => y => LtEq(y)(x);
    public static Lambda Eq         = x => y => And(LtEq(x)(y))(LtEq(y)(x));
    public static Lambda M          = x => x(x);

для различных тестов и всего кода см.: http://code.google.com/p/jigsaw-library/source/browse/trunk/Theory/EmbeddedLambdaCalculus.cs


вы можете иметь метод, который создает и возвращает выражение дерево:

public Expression GetExpression()
{

}

также построение деревьев выражений в .NET 4.0 был значительно улучшен.