Лямбда возвращает другую лямбду.
есть ли способ рекурсивно вернуть лямбду из другой лямбды?
все, что я хочу сделать, это конечный автомат, реализованный как лямбда, который возвращает лямбда, реализующий другое состояние (или 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 был значительно улучшен.