Подтвердить что ты не робот

Приложение оператора Haskell dollar

У меня возникли проблемы с пониманием того, как приложение-приложение работает с currying в haskell. Если у меня есть следующая функция:

($) :: (a -> b) -> a -> b

Я понимаю, что для частичного применения этой функции мне нужно предоставить функцию (a -> b) ($ первый аргумент).

Почему тогда можно сначала применить значение (т.е. обратные аргументы)?

($ 0) :: Num a => (a -> b) -> b

Что мне здесь не хватает?

4b9b3361

Ответ 1

($) является оператором. В Haskell любой оператор может быть записан в левом разделе (например, (x $)) или в правой части (например, ($ x)):

(x $) = (\y -> x $ y) = ($) x
($ x) = (\y -> y $ x) = flip ($) x

Обратите внимание, что единственным исключением из этого правила является (-), чтобы удобно писать отрицательные числа:

\x -> (x-) :: Num a => a -> a -> a  -- equivalent to \x -> (-) x
\x -> (-x) :: Num a => a -> a       -- equivalent to \x -> negate x

Если вы хотите скопировать запись (\y -> y - x), вы можете использовать subtract:

\x -> subtract x :: Num a => a -> a -> a  -- equivalent to \x -> flip (-) x

Ответ 2

($ 0)(\x -> x $ 0)(\x -> ($) x 0)

Если ($) :: (a -> b) -> a -> b) и мы применили второй аргумент, например (\x -> ($) x 0), имеем :: Num a => (a -> b) -> b

Ответ 3

Вы вводите в заблуждение инфиксную нотацию оператора с функцией.

> :t (($) (+1))
(($) (+1)) :: Num b => b -> b

Вот несколько форм выражений с $, для лучшего понимания:

a $b = > ($) a b

($ b) = > flip ($) b = > (\ b a → ($) a b) b = > \a → ($) a b

(a $) = > ($) a = > \b → ($) a b

Ответ 4

Обратите внимание также, что в синтаксисе Haskell буквенно-цифровые имена отличаются от имен пунктуации.

Алфавитно-цифровая функция foo1 a b по умолчанию является префиксом и становится инфиксной, если вы добавляете обратные ссылки: a `foo` b.

Функция, обозначенная пунктуацией типа $ или <*>, по умолчанию является инфиксной и становится префиксом, если вы добавляете круглые скобки ($) или (<*>). Это просто синтаксический сахар для программиста, знакомого с латинским алфавитом; это произвольное, но полезное различие между буквенно-цифровыми именами и именами пунктуации.

Оба вида функций - это просто функции, у них нет специальных семантических правил, которые мы имеем для "операторов" на С++ или Java. Это просто правила синтаксиса вокруг префикса/инфикса и обратных циклов/круглых скобок, которые различаются между функциями с пунктуацией и функциями с буквенно-цифровым именем.