When should I use $ (and can it always be replaced with parentheses)?

前端 未结 5 909
伪装坚强ぢ
伪装坚强ぢ 2021-01-04 21:31

From what I\'m reading, $ is described as \"applies a function to its arguments.\" However, it doesn\'t seem to work quite like (apply ...) in Lisp

相关标签:
5条回答
  • 2021-01-04 22:02

    $ is preferred to parentheses when the distance between the opening and closing parens would otherwise be greater than good readability warrants, or if you have several layers of nested parentheses.

    For example

    i (h (g (f x)))
    

    can be rewritten

    i $ h $ g $ f x
    

    In other words, it represents right-associative function application. This is useful because ordinary function application associates to the left, i.e. the following

    i h g f x
    

    ...can be rewritten as follows

    (((i h) g) f) x
    

    Other handy uses of the ($) function include zipping a list with it:

    zipWith ($) fs xs
    

    This applies each function in a list of functions fs to a corresponding argument in the list xs, and collects the results in a list. Contrast with sequence fs x which applies a list of functions fs to a single argument x and collects the results; and fs <*> xs which applies each function in the list fs to every element of the list xs.

    0 讨论(0)
  • 2021-01-04 22:02

    Lots of good answers above, but one omission:

    $ cannot always be replace by parentheses

    But any application of $ can be eliminated by using parentheses, and any use of ($) can be replaced by id, since $ is a specialization of the identity function. Uses of (f$) can be replaced by f, but a use like ($x) (take a function as argument and apply it to x) don't have any obvious replacement that I see.

    0 讨论(0)
  • 2021-01-04 22:12

    The documentation of ($) answers your question. Unfortunately it isn't listed in the automatically generated documentation of the Prelude.

    However it is listed in the sourcecode which you can find here:

    http://darcs.haskell.org/packages/base/Prelude.hs

    However this module doesn't define ($) directly. The following, which is imported by the former, does:

    http://darcs.haskell.org/packages/base/GHC/Base.lhs

    I included the relevant code below:

    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
    
    0 讨论(0)
  • 2021-01-04 22:13

    You're mostly understanding it right---that is, about 99% of the use of $ is to help avoid parentheses, and yes, it does appear to be preferred to parentheses in most cases.

    Note, though:

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

    That is, $ is a function; as such, it can be passed to functions, composed with, and anything else you want to do with it. I think I've seen it used by people screwing with combinators before.

    0 讨论(0)
  • 2021-01-04 22:18

    If I look at your question and the answers here, Apocalisp and you are both right:

    • $ is preferred to parentheses under certain circumstances (see his answer)
    • foo (bar quux) is certainly not bad style!

    Also, please check out difference between . (dot) and $ (dollar sign), another SO question very much related to yours.

    0 讨论(0)
提交回复
热议问题