【问题标题】:When should I use $ (and can it always be replaced with parentheses)?我什么时候应该使用 $ (它总是可以用括号代替)?
【发布时间】:2010-09-28 14:26:22
【问题描述】:

根据我的阅读,$ 被描述为“将函数应用于其参数”。然而,它似乎不像 Lisp 中的 (apply ...) 那样工作,因为它是一个二元运算符,所以它看起来唯一的作用就是有时有助于避免括号,比如 foo $ bar quux 而不是 foo (bar quux)。我理解对了吗?后一种形式是否被认为是“坏风格”?

【问题讨论】:

    标签: haskell syntax operators


    【解决方案1】:

    您的理解基本正确——也就是说,大约 99% 的 $ 使用是为了帮助避免使用括号,是的,在大多数情况下,它似乎确实比括号更受欢迎。

    请注意:

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

    也就是说,$是一个函数;因此,它可以被传递给函数,由它组成,以及任何你想用它做的事情。我想我以前见过有人用它来搞混组合器。

    【讨论】:

      【解决方案2】:

      $ 在左括号和右括号之间的距离大于良好的可读性保证时,或者如果您有多层嵌套括号时,首选括号。

      例如

      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 的每个元素。

      【讨论】:

      • 关于 $ 符号的菊花链的一个有用点是,它可以像 Unix 管道一样读取,只是从右到左。
      • 可以这样读“有点”,所以最好不要这样想。
      【解决方案3】:

      ($) 的文档回答了您的问题。不幸的是,它没有在automatically generated documentation of the Prelude 中列出。

      但是它在源代码中列出,您可以在此处找到:

      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
      

      【讨论】:

        【解决方案4】:

        上面有很多很好的答案,但遗漏了一个:

        $ 不能总是用括号代替

        但是$ 的任何应用都可以用括号消除($) 的任何应用都可以用id 代替,因为$ 是恒等函数(f$) 的使用可以被f 替换,但是像($x) 这样的使用(将函数作为参数并将其应用于x)在我看来没有任何明显的替换。

        【讨论】:

        • ($ x) 很容易被 (\f -> f x) 替换
        【解决方案5】:

        如果我在这里查看您的问题和答案,Apocalisp 和您都是对的:

        • $ 优于括号在某些情况下(见他的回答)
        • foo (bar quux) 风格肯定不错!

        另外,请查看difference between . (dot) and $ (dollar sign),另一个与您非常相关的 SO 问题。

        【讨论】:

          猜你喜欢
          • 2011-01-18
          • 2011-08-18
          • 2017-03-21
          • 2010-09-05
          相关资源
          最近更新 更多