@plyk

Как понять каррирование в Haskell?

В своём прошлом вопросе я примерно понял что такое частичное применение: https://qna.habr.com/q/1218774
Однако вопрос с каррированием остался открытым, как его понять?

Я пока что встал на простейшей как некоторые думают функции map, вот её сигнатура:
map :: (a -> b) -> [a] -> [b]
Итак, что такое эти ваши скобки? Ну допустим они обозначают функцию с одним аргументом типа a и возвращающую тип b.
Однако как быть с [a]? Это типо первый аргумент map ещё не вычисляя себя возвращает функцию(не b) принимающую [a]? А потом типо идёт назад и возвращает b который потом возвращается как [b], в то время как сам [a] по сути map'у то и не нужен.
Как всё это понять? Я ещё сомневаюсь что тут вообще указаны агрументы а не типы возвращаемых значений, то есть тут не указано то, что я в map посылаю. Хотя эксперименты в ghci указывают на обратное.
  • Вопрос задан
  • 112 просмотров
Пригласить эксперта
Ответы на вопрос 2
mayton2019
@mayton2019
Bigdata Engineer
Лямбда применяется к массиву типа A и возвращает массив типа B.

Вот и все.
Ответ написан
@AlexSku
не буду отвечать из-за модератора
1) Каррирование позволяет функции скармливать аргументы по-одному (несколько, не все сразу), т.е. возможно частичное применение.
Напр., (+) x y имеет тип:
a -> a -> a
Чтобы понять, какая стрелка первая, пользуемся ассоциативностью (здесь правой):
а -> (a -> a)
Поэтому в Haskell все каррированные функции это функции одного аргумента. Формально сложение, это функция, принимающая один аргумент (типа а) и выдающая функцию (типа a -> a). Но это философия. Для удобства и скобки можно не писать, и предоставить (если нужно) плюсу два аргумента (тогда результатом будет число).
2) В формальном подходе map тоже функция одного аргумента:
(a -> b) -> ([a] -> [b])
(это классическое определение функтора по теории категорий).
Но благодаря каррированию, можно также представить map как функцию (высшего порядка, т.к. первый аргумент - функция) принимающую два аргумента: функцию и список. Результат - список.
Первый аргумент типа (a -> b), второй типа [a].
3) там, где :: , пишутся типы аргументов и результата. Сами аргументы и тело функции (выражение) пишутся ниже через =.
(при этом может быть применён бесточечный стиль, когда не все аргументы перечислены, напр.:
mysum = (+)
или mysum x = (+) x
или mysum x y = (+) x y -- здесь все аргументы)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы