Haskell: понимание функции карты при использовании с лямбда-функцией - PullRequest
3 голосов
/ 14 июня 2019

У меня есть два следующих выражения Haskell:

map (\f x -> f x 5) [(-),(+),(*)]
map (\f x -> f 5 x) [(-),(+),(*)]

И я пытаюсь выяснить, эквивалентно ли любое из приведенных выше выражений следующему выражению:

map ($ 5) [(-),(+),(*)]

Я пытаюсь понять, в чем разница между первыми двумя выражениями. Поскольку для обоих выражений в лямбда-функцию передается только один параметр (например, оператор), функция будет применена частично.

Правильно ли говорить, что элементы в списке результатов из первого выражения будут:

(1) - x 5 = (- x) 5

(2) + x 5 = (+ x) 5

(3) * x 5 = (* x) 5

А для второго выражения:

(1) - 5 x = (- 5) x

(2) + 5 x = (+ 5) x

(3) * 5 x = (* 5) x

Однако я не думаю, что какое-либо выражение эквивалентно map ($ 5) [(-),(+),(*)]. Это потому, что (- x) 5 (где x - число) выдает ошибку в GHCI и является недопустимым выражением. Аналогично (- 5) x также выдает ошибку. С другой стороны, map ($ 5) [(-)] приводит к функции, которая берет число и вычитает его из 5. Это рассуждение правильно? Любые идеи приветствуются.

1 Ответ

4 голосов
/ 14 июня 2019

(- 5) 5 выдает ошибку, потому что префикс минус - это особый случай в синтаксисе языка: (- 5) означает минус пять, число, а не функция, которая вычитает пять (см. Также: Curry вычитание ). В связи с этим я остановлюсь на случае (+), который не является исключительным.

Во втором выражении, map (\f x -> f 5 x) [(-),(+),(*)], второй элемент списка результатов будет:

(\f x -> f 5 x) (+)

При оценке таких вещей вручную важно соблюдать осторожность, чтобы не перепутать префиксное, инфиксное и секционированное использование операторов. Приложение здесь выдает ...

\x -> (+) 5 x  -- Prefix syntax (note the parentheses around the operator)

... что эквивалентно ...

\x -> 5 + x  -- Infix syntax

... и до:

\x -> (5 +) x  -- Left section
\x -> (+ x) 5  -- Right section

(5 +)          -- Left section, pointfree

Таким образом, разделы, которые создаются по шаблону после использования инфиксных операторов, должны быть наоборот относительно вашего вопроса. Что касается map ($ 5) [(-),(+),(*)], оно эквивалентно map (\f x -> f 5 x) [(-),(+),(*)], вашему второму выражению. Вы можете подтвердить это, используя тот факт, что ($) f x = f x, чтобы выяснить, что такое правый раздел ($ 5).

...