Шаг 22.
Основы языка Haskell. Основные типы данных, операции, способы определения функций. Определение функций с помощью охраняющих выражений

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

Определение.
Охраняющим выражением называется выражение, накладывающее ограничения на аргументы функции и возвращающее значение True или False.

    Определение функций с помощью охраняющих выражений имеет следующий синтаксис:

   <Имя_функции> x1 x2 ... xk | <Условие_1> = <Выражение_1>
                              | <Условие_2> = <Выражение_2>
                                           ...
                              | otherwise   = <Выражение_n>

    При определении функции охраняющие выражения (<Условие_i>, i∈N; otherwise) записываются после образцов (x1,x2,...,xk), но перед выражениями, являющими собой описание вычислительного процесса (<Выражение_i>, i∈N). Символ "|" используется для разграничения образцов и охраняющих выражений.

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


   Замечание. Вместо служебного слова otherwise можно использовать слово True, которое называется конструктором типа.

    Демонстрационные примеры.

   -- Демонстрация представления функций с помощью:
   --  (1) с помощью охраняющих выражений;
   --  (2) композиции функций
   ----------------------------------------------
   -- Функция возвращает наибольшее из двух чисел
   -- (с помощью охраняющих выражений)
   -----------------------------------
   max2:: Integer -> Integer -> Integer
   max2 m n | m>n  = m
            | True = n
   ----------------------------------------------
   -- Функция возвращает наибольшее из трёх чисел
   -- (с помощью охраняющих выражений)
   -----------------------------------
   max3:: Int -> Int -> Int -> Int
   max3 m n k | m>n && m>k = m
              | n>k        = n
              | True       = k
   ----------------------------------------------
   -- Функция возвращает наибольшее из трёх чисел
   -- (с помощью композиции функций)
   ------------------------------------------------
   max3':: Integer -> Integer -> Integer -> Integer
   max3' m n k = max2 (max2 m n) k
   ----------------------------------------------
   -- Функция возвращает наибольшее из трёх чисел
   -- (с помощью комбинаторов)
   -------------------------------------------------
   max3'':: Integer -> Integer -> Integer -> Integer
   max3'' = (.) ((.) max2) max2
   -------------------------------------------------
   -- Функция возвращает наибольшее из четырёх чисел
   -- (с помощью композиции функций)
   ---------------------------------------
   max4:: Integer -> Integer -> Integer -> Integer -> Integer
   max4 m n k l = max2 (max2 m n) (max2 k l) 
   -----------------------------------------
   -- Неудачные тестовые примеры:
   ------------------------------
   test1 =   max2  4  5     == 5
          && max3  4  5 6   == 6 
          && max3' 4  5 6   == 6
          && max4  4  5 6 7 == 7
   -----------------------------
   test2 =   max3'' 4 5 6 == 6 
          && max3'' 4 5 6 == 6
          && max3'' 5 6 7 == 7
Файл с примерами можно взять здесь.
   -- Демонстрация синтаксиса и семантики охраняющих выражений 
   -----------------------------------------------------------
   -- Функция, возвращающая абсолютное значение n
   ----------------------------------------------
   abs':: Double -> Double
   abs' n | n<0  = -n
          | n>=0 = n 
   -------------------------------------------------
   -- Функция, возвращающая наибольшее из двух чисел
   -------------------------------------------------
   max':: Double -> Double -> Double
   max' m n | m>n  = m
            | m<=n = n
   -----------------------------------------------------------
   -- Функция, возвращающая наименьшее из двух чисел с помощью
   -- вывода некоторого текста на экран дисплея
   --------------------------------------------
   max1':: Int -> Int -> String
   max1' m n | m<n  = "Первое число меньше второго"
             | m>n  = "Второе число меньше первого"
             | True = "Значения равны"
   -----------------------------------
   -- Неудачные тестовые примеры:
   ------------------------------
   test = test1 && test2 && test3
   -------------------------------------------
   test1 =   abs' 22                     == 22
          && abs' (-22)                  == 22
          && abs' 0                      == 0
          && abs' 2222222222222222222    == 2222222222222222222
          && abs' (-2222222222222222222) == 2222222222222222222
          && abs' 2.222222222222222      == 2.222222222222222
          && abs' (-2.222222222222222)   == 2.222222222222222
   ----------------------------------------------------------
   test2 =   max' 5 4                           == 5
          && max' (-3) (-1)                     == (-1)
          && max' 0 0                           == 0
          && max' 99999999 999999991            == 999999991
          && max' 99999999999 999999999991      == 999999999991
          && max' (-99999999999) (-999999999991)==(-99999999999)
          && max' 99999999999 999999999991      == 999999999991
          && max' (-99999999999) (-999999999991)==(-99999999999)
          && max' 999.99999999 99.9999999991    == 999.99999999
          && max' 999.99999999 999.99999999     == 999.99999999
   ------------------------------------------------------------
   test3 =   max1' 4 5       == "Первое число меньше второго"
          && max1' 5 (-12)   == "Второе число меньше первого"
          && max1' (-5) (-5) == "Значения равны"
Файл с примерами можно взять здесь.

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




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