Почему `($ 4) (> 3)` эквивалентно `4> 3`?

Я заметил, что сегодня я играю с Haskell, что можно сделать что-то вроде

($ 4) (> 3)

что дает True. Что здесь происходит? Было бы здорово иметь некоторую интуицию.

Мое предположение? Похоже, что ($ 4) является неполным функциональным приложением, но я смущен тем, что $ - это инфиксный оператор, так что не должно выглядеть как (4 $)? Это не скомпилируется, поэтому явно нет, что заставляет меня поверить, что я действительно не понимаю, что происходит. Термин (>3) имеет смысл для меня, потому что если вы поставляете что-то вроде (\x -> x 4) (>3), вы получите тот же результат.

Ответ 1

($ 4) - это то, что называется section. Это способ частичного применения инфиксного оператора, но с правой стороны вместо левой. Это точно эквивалентно (flip ($) 4).

Аналогично, ( > 3) является сечением.

($ 4) (> 3)

можно переписать как

(flip ($) 4) (> 3)

что совпадает с

flip ($) 4 (> 3)

что совпадает с

(> 3) $ 4

И на этом этапе должно быть ясно, что это сводится к (4 > 3).

Ответ 2

Вы можете частично применить оператор infix с обеих сторон. Для коммутативных операторов, таких как +, не имеет значения, говорите ли вы (+ 1) или (1 +), но, например, для деления вы можете предоставить либо дивиденд (5 /), либо divisor (/ 5).

Оператор приложения функции принимает функцию в качестве левого операнда и параметр в качестве правого операнда (f $ x), поэтому вы можете частично применить его либо с помощью функции (f $), либо с параметром ($ x). Таким образом,

($ 4) (> 3)

Сначала вы частично примените $-оператор с параметром 4 и поставьте его функцией (> 3). Так что это по существу становится

(> 3) $ 4

То же, что и (4 > 3).

Ответ 3

($ 4) - это функция, которая принимает функцию и применяет к ней 4.

(> 3) - это функция, которая принимает число и проверяет, больше ли оно.

Таким образом, передавая последнюю функцию первому, вы по существу применяете 4 к функции, которая проверяет, превышает ли ее входной сигнал больше 3, и вы получаете True.