Главная » C# » Рекурсия – функциональное программирование

0

Мы   видели,   что   элементы   коллекции   можно   обрабатывать   в   цикле   с   помощью оператора  foreach. Для  этих  целей  функциональные  языки  применяют  не  циклы, а рекурсию.  Скажем,  что  нам  нужно  выполнить  счет  от  нуля  до  определенного  чиа.  Это  можно  сделать  посредством  лямбда-выражения  следующим  образом: delegate void Counter(int iterations);

Counter RecursiveCount = (iterations) => { if (iterations >0 ) {

RecursiveCount(iterations – 1);

}

Console.WriteLine("Curr count( " + iterations + ")");

} ;

RecursiveCount(lO);

В данном  исходном  коде  определяется  делегат,  который  объявляет  метод Counter(), имеющий единственный параметр iterations. Посредством этого параметра  можно   вести  счет,   сколько  еще  раз   необходимо  выполнить  рекурсию. В реализации лямбда-выражения рекурсия активируется посредством вызова перенной Recurs iveCount, которая является лямбда-выражением с присвоенным знением. Но, несмотря  на то,  что,  казалось бы, данный  подход должен  работать, т.  к. он вроде бы имеет смысл, данное рекурсивное выражение не работает и даже не компилируется.

Чтобы   заставить   рекурсию  с   использованием  лямбда-выражений   работать,   нужен намного   более   сложный   код.   Этот   подход  обсуждается   в  двух  блогах:   Веснера Мойза    (Wesner    Moise)    по    адресу    http://wesnerm.blogs.coni/net_undocumented/ 2007/03/anonymous_recur.html   и   MSDN   по   адресу   http://blogs.msdn.com/madst/ archive/2007/05/ll/recursive-lambda-expressions.aspx.    Если    вы    уделите    немного времени  этим  блогам,  то  очень  быстро  осознаете,  что  заставить  работать  рекурсию с   применением   лямбда-выражений —   крайне   сложная   задача.   Так  зачем   вообще делать  это?  А  кто  говорит,  что это  нужно делать?  Наоборот,  следует  избегать  этого

подхода, т. к. для него требуется слишком много знаний о подробностях лямбдыражений.

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

delegate void Counter(Counter counter, int value); class Program {

static void Main( string[] args) {

Counter counter = delegate(Counter paramCounter, int iterations) { if (iterations > 0) {

paramCounter(paramCounter, iterations – 1);

}

Console.WriteLine("Curr count( " + iterations + ")");

} ;

counter(counter, 10);

}

}

При вызове делегата в нем необходимо передать элемент, который будет  вызаться рекурсивно (counter (counter…)). Но это может вызвать ошибки и непостнство в работе метода.

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

  • Комментарии