Для некоторых функций возможен инфиксный способ записи, такие функции обычно представляют собой простые бинарные операции. Вот как, например, определены операции конкатенации списков и композиции функций:
Пример 4.4. Инфиксная операция конкатенации списков.
(++) :: [a] -> [a] -> [a]
[] ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)
Пример 4.5. Инфиксная операция композиции функций.
(.) :: (b -> c) -> (a -> b) -> (a -> c)
f . g = \x -> f (g x)
Т.к. инфиксные операции всё-таки являются функциями в смысле Haskell’а, т.е. они каррированы, то имеет смысл обеспечить возможность частичного применения таких функций. Для этих целей имеется специальная запись, которая в Haskell’е носит название "секция":
(x ++) = \x -> (x ++ y)
(++ y) = \y -> (x ++ y)
(++) = \x y -> (x ++ y)
Выше показаны три секции, каждая из которых определяет инфиксную операцию конкатенации списков в соответствии с количеством переданных ей аргументов. Использование круглых скобок в записи секций является обязательным.
Если какая-либо функция принимает два параметра, то её также можно записывать в инфиксной форме. Однако если просто записать между параметрами имя функции — это будет ошибкой, т.к. в строгой нотации Haskell’а, это будет просто двойным применением, причем в одном применении не будет хватать одного операнда. Для того чтобы записать функцию в инфиксной форме, её имя необходимо заключить в символы обратного апострофа — `.
Для вновь определённых инфиксных операций возможно определение порядка вычисления. Для этого в Haskell’е есть зарезервированное слово infixr, которое назначает заданной операции степень её значимости (порядок выполнения) в интервале от 0 до 9, при этом 9 объявляется самой сильной степенью значимости (число 10 также входит в этот интервал, именно эту степень имеет операция применения). Вот так определяются степени для определенных в примерах 4.4 и 4.5 операций:
infixr 5 ++
infixr 9 .
Остается отметить, что в Haskell’е все функции являются нестрогими, т.е. все они поддерживают отложенные вычисления. Например, если какая-то функция определена как:
bot = bot
При вызове такой функции произойдет ошибка, и обычно такие ошибки сложно отслеживать. Но если есть некая константная функция, которая определена как:
constant_1 x = 1
То при вызове конструкции (constant_1 bot) никакой ошибки не произойдёт, т.к. значение функции bot в этом случае не вычислялось бы (вычисления отложенные, значение вычисляется только тогда, когда оно действительно требуется). Результатом вычисления естественно будет число 1.