Применение частичных функций на самом деле не является отличительной особенностью Haskell; это просто следствие каррированных функций.
map :: (a -> b) -> [a] -> [b]
В таком языке, как Python, map
всегда принимает два аргумента: функцию типа a -> b
и список типа [a]
.
map(f, [x, y, z]) == [f(x), f(y), f(z)]
Это требует, чтобы вы делали вид, что синтаксис ->
предназначен только для галочки, и что ->
между (a -> b)
и [a]
на самом деле не то же самое, что между [a] -> [b]
. Однако это не так; это точно такой же оператор, и он правоассоциативен. Тип map
может быть явно заключен в скобки как
map :: (a -> b) -> ([a] -> [b])
и внезапно кажется гораздо менее интересным, что вы можете указать только один аргумент (функцию) для map
и получить в ответ новую функцию типа [a] -> [b]
. Вот и все частичное применение функций: использование того факта, что все функции каррированы.
На самом деле вы никогда не даете функции более одного аргумента. Чтобы согласиться с тем, что ->
является правоассоциативным, функция application является лево-ассоциативной, что означает вызов с несколькими аргументами, например
map f [1,2,3]
на самом деле два приложения-функции, что становится яснее, если мы заключим его в скобки.
(map f) [1,2,3]
map
сначала "частично" применяется к одному аргументу f
, который возвращает новую функцию. Затем эта функция применяется к [1,2,3]
для получения окончательного результата.
person
chepner
schedule
14.07.2016
<*>
дляApplicative
определен вf (a -> b)
, функторе функции с одним аргументом, но поскольку все функции каррируются, все функции имеют один аргумент, поэтому функция<*>
работает с функциями произвольной арности. - person Alexis King   schedule 14.07.2016flip id
? Что оно делает? - person melpomene   schedule 14.07.2016printf
, требуется глубочайшее понимание, но я бы не советовал вам сразу лезть в подобную сложность. - person dfeuer   schedule 14.07.2016