Шаг 106.
Основы языка Haskell. Функционалы (функции высшего порядка). Функционалы из Prelude. Функционал для организации циклических процессов

    На этом шаге мы рассмотрим этот функционал.

    В языке 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
Файл с примерами можно взять здесь.


   Замечание. Семантика функционала until напоминает семантику функционала iterate, формирующего бесконечный список промежуточных результатов, последний элемент которого является возвращаемым значением функции.

    На следующем шаге мы рассмотрим прагматику функционалов.




Предыдущий шаг Содержание Следующий шаг