На этом шаге мы рассмотрим этот функционал.
В языке Haskell существует функционал, способствующий организации циклических вычислений заданной функции с передачей в качестве параметра на очередной итерации предыдущего вычисленного значения.
Синтаксис и семантика функционала
until:: (a -> Bool) -> (a -> a) -> a -> a until p f x 0 = if (p x) then x else until p f (f x)
В качестве сигнала об остановке цикла используется предикат, передаваемый первым аргументом: когда его значение становится истинным, выполнение циклического процесса прекращается.
Приведем демонстрационные примеры.
-- Демонстрация синтаксиса и семантики функционала -- until -- **************************************** -- Функция итеративно возвращает результат -- вычисления квадратного корня из числа x, -- -- f1 x = (sqrt ... (sqrt (sqrt x))), -- -- пока не будет получено число, меньшее 2 ------------------------------------------ f1:: Float -> Float f1 x = until (< 2) sqrt x -- until (\z -> z < 2) (\z -> sqrt z) x --------------------------------------------- -- Функция итеративно возвращает результат -- вычисления значения функции sin x -- -- f2 x = sin (sin ... (sin (sin x))) -- -- пока не будет получено число, меньшее 0.01 --------------------------------------------- f2:: Float -> Float f2 x = until (< 0.01) sin x -- until (\z -> z < 0.01) (\z -> sin z) x ----------------------------------------------- -- Функция возвращает минимальное значение x, -- для которого -- -- s+x*g<f, -- -- где s, g, f - функции-константы ---------------------------------- awk:: Integer -> Integer awk x = until (\z -> s+z*g>f) (\z -> z+1) x where s = 4 g = 5 f = 30 -- *************************** -- Неудачные тестовые примеры: ------------------------------------------ test1 = f1 25 == sqrt (sqrt (sqrt 25)) && f1 1024 == sqrt (sqrt (sqrt (sqrt 1024))) && abs (f1 25 - 1.49535) < 0.00001 ----------------------------------------- -- Удачный тестовый пример: ---------------------------------------- test2 = abs (f1 25 - 1.49535) < 0.000001 -- ************************************* test3 = f2 1.5 test4 = last (take 297 (iterate sin 1.5)) ----------------------------------------- test5 = awk 0==6
На следующем шаге мы рассмотрим прагматику функционалов.