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

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

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

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

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

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

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

4 ответа

Решение

($) это оператор. В 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

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

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

Вы путаете запись инфиксного оператора с функцией.

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

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

a $ b => ($) ab

($ b) => flip ($) b => (\ ba -> ($) ab) b => \ a -> ($) ab

(a $) => ($) a => \ b -> ($) ab

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

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

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

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

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