Я полагаю, это то же самое, что HTTP использует протокол TCP.
$
предпочтен круглым скобкам, когда расстояние между открытием и закрытием parens иначе было бы больше, чем хорошие ордеры удобочитаемости, или если у Вас есть несколько слоев вложенных круглых скобок.
Например,
i (h (g (f x)))
может быть переписан
i $ h $ g $ f x
Другими словами, это представляет правоассоциативное функциональное приложение. Это полезно, потому что приложение обычной функции связывается налево, т.е. следующее
i h g f x
... может быть переписан следующим образом
(((i h) g) f) x
Другое удобное использование ($)
функция включает архивирование списка с ним:
zipWith ($) fs xs
Это применяет каждую функцию в списке функций fs
к соответствующему аргументу в списке xs
, и собирает результаты в списке. Контраст с sequence fs x
который применяет список функций fs
к отдельному аргументу x
и собирает результаты; и fs <*> xs
который применяет каждую функцию в списке fs
к каждому элементу списка xs
.
Вы главным образом понимаете это правильный---то есть, приблизительно 99% использования $ должны помочь избежать круглых скобок, и да, это, действительно кажется, предпочтено круглым скобкам в большинстве случаев.
Отметьте, хотя:
> :t ($) ($) :: (a -> b) -> a -> b
Таким образом, $ является функцией; как таковой, это может быть передано функциям, составленным с, и что-либо еще, что Вы хотите сделать с ним. Я думаю, что видел используемый людьми, завинчивающими с combinators прежде.
Документация ($) отвечает на Ваш вопрос. К сожалению, это не перечислено в автоматически сгенерированной документации Вводной части.
Однако это перечислено в исходном коде, который можно найти здесь:
http://darcs.haskell.org/packages/base/Prelude.hs
Однако этот модуль не определяет ($) непосредственно. Следующее, которое импортируется первым, делает:
http://darcs.haskell.org/packages/base/GHC/Base.lhs
Я включал соответствующие нормы ниже:
infixr 0 $
...
-- | Application operator. This operator is redundant, since ordinary
-- application @(f x)@ means the same as @(f '$' x)@. However, '$' has
-- low, right-associative binding precedence, so it sometimes allows
-- parentheses to be omitted; for example:
--
-- > f $ g $ h x = f (g (h x))
--
-- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@,
-- or @'Data.List.zipWith' ('$') fs xs@.
{-# INLINE ($) #-}
($) :: (a -> b) -> a -> b
f $ x = f x
Много хороших ответов выше, но один пропуск:
$
не может всегда быть замена круглыми скобками
Но любое приложение $
может быть устранен при помощи круглых скобок и любого использования ($)
может быть заменен id
, с тех пор $
специализация тождественного отображения. Использование (f$)
может быть заменен f
, но использование как ($x)
(возьмите функцию в качестве аргумента и примените его к x
) не имейте никакой очевидной замены, которую я вижу.
Если я посмотрю на ваш вопрос и ответы здесь, Апокалисп и вы оба правы:
$
предпочтительнее скобок при определенных обстоятельствах (см. Его ответ) foo ( bar quux)
определенно неплохой стиль! Также, пожалуйста, проверьте разницу между. (точка) и $ (знак доллара) , еще один вопрос SO, очень связанный с вашим.