На этом шаге мы рассмотрим такий тип рекурсии.
Рассмотрим демонстрационные примеры.
-- Демонстрация сложной рекурсии на числовых структурах -- на примере вычисления значения функции "91-МакКарти" -- -- F(n)=If n>100 -- then n-10 -- else F(F(F(n+21))) -- *************************** f91:: Integer -> Integer f91 n | n>100 = n-10 | True = f91 (f91 (f91 (n+21))) -- *********************************** -- Неудачные тестовые примеры: ------------------------------ test = f91 11==91 && f91 22==91 && f91 96==91 && f91 99==91 && f91 101==91 && f91 102==92
Продемонстрируем с помощью рекурсии высших порядков тот факт, что интерпретатор языка Haskell использует нормальный порядок β-редукции при вычислениях.
-- Демонстрация принятой в языке Haskell семантики вы- -- числений, заключающейся в выборе для вычислений при -- рекурсивном вызове самой внешней функции (так назы- -- ваемая нормальная форма бета-редукции). -- Поясним сказанное с помощью следующей функции: -- -- ¦1, если x=0; -- f(x,y)=¦ -- ¦f(x-1,f(x,y)), если x>0. -- -- Значение f(1,0) можно вычислить двумя способами: -- (1) с помощью нормальной формы бета-редукции: -- -- f(1,0)=f(0,f(1,0))=1; -- -- (2) с помощью аппликативного порядка редукции: -- -- f(1,0)=f(0,f(1,0))=f(0,f(0,f(1,0)))= -- =f(0,f(0,f(0,f(1,0))))=... -- -- Возникает неоднозначность процесса вычисления... -- ************************************************ func1:: Integer -> Integer -> Integer func1 x y | x==0 = 1 | True = func1 (x-1) (func1 x y) ------------------------------------------ func2:: Integer -> Integer -> Integer func2 x y | y==0 = 1 | True = func2 (func2 x y) (y-1) ------------------------------------------ -- Неудачные тестовые примеры: ------------------------------ test1 = func1 1 0 == 1 && func1 1 1 == 1 && func1 2 0 == 1 && func1 123 34 == 1 --------------------------- test2 = func2 1 0 == 1 && func2 1 1 == 1 && func2 0 2 == 1 && func2 34 123 == 1
На следующем шаге мы рассмотрим трансформацию функций для приведения к простой рекурсии.