На этом шаге мы рассмотрим данный способ задания функций.
Парадигма функционального программирования основана на математическом формализме λ-исчисления, используемом при описании функций.
Напомним, что в λ-исчислении имеется математическая абстракция для записи функций. Например:
При этом тип λ-абстракции определяется так же, как и тип функций.
На языке Haskell λ-абстракция кодируется следующим образом:
Символы λ-исчисления | Символы Haskell |
---|---|
λ | \ |
. | -> |
Сопоставим записи безымянных функций в λ-исчислении и в языке программирования Haskell.
λ-исчисление | Язык Haskell |
---|---|
λx.(x+1) | \x -> x+1 |
λx. λy.(x+y) | \x -> \y -> x+y |
λxy.(x+y) | \x y -> x+y |
λz.λy.λx.(x+y+z) | \z -> \y -> \x -> x+y+z |
Таким образом, в языке Haskell можно определять функции так:
inc = \x -> x+1 add1 = \x -> \y -> x+y add2 = \x y -> x+y summa = \z -> \y -> \x -> (x+y+z)
В заключение приведем примеры задания функций с помощью такой нотации:
-- Демонстрация определения безымянных функций -- с помощью лямбда-нотации -- *************************************** -- Функция одного аргумента, увеличивающая -- значение аргумента на 1 -------------------------- inc:: Int -> Int inc = \x -> x + 1 --------------------------------------------- -- Функция двух аргументов, вычисляющая сумму -- двух чисел ------------------------ add1:: Int -> Int -> Int add1 = \x -> \y -> x + y ------------------------------------------- -- Функция двух аргументов (!), вычисляющая -- сумму двух чисел ------------------------ add2:: Int -> Int -> Int add2 x = \y -> x + y ------------------------------------------- -- Функции, моделирующая композицию функций -- с использованием безымянных функций -------------------------------------- f1 x = (.) (\x -> x+5) (\z -> z^2) x ------------------------------------ f2 x = (\x -> x+5) ((\z -> z^2) x) -- ******************************* -- Неудачные тестовые примеры: ------------------------------ test1 = inc 2^31 == 1264544299 --------------------------------------------------------- test2 = (\x -> \y -> \z -> x^2 + y^2 + z^2) 2 3 4 == 29 && (\x y z -> x * y * z) 2 3 4 == 24 -------------------------------------------------- && add1 12 13 == 25 && add2 12 13 == 25 && f2 3 == 14 && f1 3 == 14 --------------------------------------------- test3 = ((\x -> x + 5):: Int -> Int) 10 == 15
На следующем шаге мы рассмотрим понятие о выводе типов.