Понимание функции карты, когда первый аргумент использует flip

Я узнаю о функциях высшего порядка из книги «Изучите Haskell во благо!» Миран Липовача. Я знаю, что функция flip принимает функцию и возвращает функцию, аналогичную исходной, но с перевернутыми первыми двумя аргументами.

Я не совсем понимаю, как работает следующий пример с функцией карты.

ghci> map (flip subtract 20) [1,2,3,4]
[19,18,17,16]

Map принимает функцию и применяет ее к каждому элементу списка, в результате чего получается новый список. Но поскольку флип — это функция, которую принимает карта, с параметрами subtract 20 [1,2,3,4], будет ли результирующая функция 20 subtract [1,2,3,4]?

Я не думаю, что это правильно, поскольку такое значение, как 19, создается только при вводе subtract 1 20. Я не уверен, как вычитание будет работать в приведенном выше примере для создания выходного списка.

По сути, flip иногда не нужен, если вы можете использовать инфиксную запись функции. Например `subtract` 20. Так что можете делать map (`subtract` 20) [1,2,3,4]. Или лучше map ((-) 20) [1,2,3,4]

Redu 08.06.2019 19:09

Скобки важны — нельзя «разлагать» (flip subtract 20).

molbdnilo 08.06.2019 20:25
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
2
359
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Нет, здесь функция map :: (a -> b) -> [a] -> [b] принимает (flip subtract 20), это параметр, который вы передаете map. Итак, это означает, что:

map (flip subtract 20) [1,2,3,4]

эквивалентно:

[flip subtract 20 1, flip subtract 20 2, flip subtract 20 3, flip subtract 20 4]

flip :: (a -> b -> c) -> b -> a -> c — это функция, которая принимает функцию и меняет параметры. Таким образом, flip subtract 20 семантически эквивалентно \x -> subtract x 20. Таким образом, наш список эквивалентен:

[subtract 1 20, subtract 2 20, subtract 3 20, subtract 4 20]

subtract :: Num a => a -> a -> a — это «перевернутая» версия (-), поэтому она эквивалентна:

[20 - 1, 20 - 2, 20 - 3, 20 - 4]

и, таким образом, эквивалентно:

Prelude> map (flip subtract 20) [1,2,3,4]
[19,18,17,16]

Таким образом, более короткая версия приведенного выше выражения:

map (20 -) [1,2,3,4]

flip имеет следующий функционал: применяет заданную функцию к двум заданным параметрам в обратном порядке («перевернуто»).

Prelude> :t flip
flip :: (a -> b -> c) -> b -> a -> c

Вот как (flip subtract 20) становится функцией f(x) = 20-x, где (subtract 20) соответствует g(x) = x-20.

Затем f применяется к каждому элементу списка с помощью функции карты.

But since flip is the function map takes...

Нет. map принимает функцию в качестве первого параметра — здесь это flip subtract 20. Это действительно функция, как мы сейчас увидим (если бы это было не так, компилятор выдал бы ошибку, потому что он ожидает здесь функцию).

Мы начнем с вычесть, который на самом деле определяется как flip (-). Это означает, что flip subtract — это просто (-), или:

flip subtract = \a b -> a - b

в отличие от

subtract = \a b -> b - a

Итак, каррируя:

flip subtract a = \b -> a - b

и подставив в 20:

flip subtract 20 = \b -> 20 - b

Итак, flip subtract 20 действительно является функцией, которая возвращает результат вычитания своего аргумента из 20. mapпроверка этой функции по заданному списку дает показанный результат.

Другие вопросы по теме