На этом шаге мы рассмотрим принципы создания таких операций.
Ассоциативность и приоритет операции задаётся с помощью объявления, которое называется infix-объявлением и имеет такой синтаксис:
<infix-объявление>::=<Ассоциативность> [<Приоритет>] Операция1, Операция2,..., Операцияn <Ассоциативность>::=infixl¦infixr¦infix <Приоритет>::= 0¦1¦2¦3¦4¦5¦6¦7¦8¦9
infix-объявление можно разместить всюду, где можно разместить сигнатуру типа (объявление типа, назначение типа). Для любой операции можно задать не более одного infix-объявления.
По умолчанию (если отсутствует infix-объявление) операция считается объявленной как
infixl 9
Демонстрационные примеры.
-- Демонстрация конструирования собственной операции -- "композиция функций" с указанием имени операции, -- её ассоциативности и приоритета ---------------------------------- infixr 9 >.> (>.>):: (Float -> Float) -> (Float -> Float) -> (Float -> Float) f >.> g = f . g ------------------------------------------------------------ -- Демонстрация определения собственной операции "композиция -- функций" с помощью лямбда-функций (безымянных функций) --------------------------------------------------------- ($.$):: (Float -> Float) -> (Float -> Float) -> (Float -> Float) f $.$ g = \x -> f (g x) ------------------------------ -- Неудачные тестовые примеры: -------------------------------------------- test1 = (asin >.> sin >.> acos >.> cos) 0.45 test2 = (log >.> exp >.> exp >.> log) 0.45 ------------------------------------------- test3 = (sin $.$ asin) 0.45 test4 = ((\x -> x+1) $.$ (\y -> y-1)) 23
-- Демонстрация конструирования новой операции, написанной -- на языке программирования Curry и дословно переписанной -- на язык Haskell ------------------ infixl 8 -** (-**):: Integer -> Integer -> Integer a -** b = if b>=0 then accum 1 a b else undefined where accum x y z | z==0 = x | True = accum aux (y*y) (z `div` 2) where aux = if z `mod` 2==1 then x*y else x -------------------------------------- -- Неудачные тестовые примеры: -------------------------------------- test = map (2 -**) [0,10,20,30,40]== [1,1024,1048576,1073741824,1099511627776] && map (2 ^) [0,10,20,30,40]== [1,1024,1048576,1073741824,1099511627776]
На следующем шаге мы рассмотрим понятие "чистота языка программирования".