Предположим, что имеется некоторая функция, выводящая приветствие:
printHello::(String->String)->String->String
printHello f x = «Hello, » ++ f x ++ «!»
Поприветствуем Васю:
ghci> printHello (x->x) «Vasya»
«Hello, Vasya!»
shortName::String->String->String->String
shortName [] _ xs = xs
shortName (x:_) [] xs = x : «. » ++ xs
shortName (x:_) (y:_) xs = x : ‘.’ : y : «. » ++ xs
ghci> printHello (x->x) $ shortName «Vasiliy» «Vasilievich» «Vasiliev»
«Hello, V.V. Vasiliev!»
Однако, благодаря возможности частичного применения функций, мы спокойно можем передать shortName первым параметром с двумя аргументами вместо трёх (третий [фамилия] будет передан ей функцией printHello):
ghci> let n = shortName «Vasiliy» «Vasilievich»
ghci> printHello n «Vasiliev»
«Hello, V.V. Vasiliev!»
или так:
ghci> printHello (shortName «Vasiliy» «Vasilievich») «Vasiliev»
«Hello, V.V. Vasiliev!»
Поскольку в данном случае в shortName передаётся два параметра вместо трёх, то генерируется промежуточная функция, сигнатура которой совпадает с ожидаемой. Этой сгенерированной функции printHello передаёт в качестве параметра фамилию, что собственно и приводит к запуску функции shortName. В результате получаем ожидаемую строку.
Вывод
Возможность частичного применения функций может представлять интерес тем, что позволяет нам «прозрачно» передавать и использовать функции, имеющие сигнатуру отличную от ожидаемой. За счёт этого код получается более кратким, т.к. не нужно создавать дополнительные варианты функций под различные требующиеся сигнатуры.