我什么时候应该使用$(并且它总是可以用括号替换)?

时间:2008-12-28 08:56:59

标签: haskell syntax operators

从我正在阅读的内容来看,$被描述为“将函数应用于其参数”。但是,它似乎与Lisp中的(apply ...)完全不同,因为它是一个二元运算符,所以它看起来真的唯一有助于避免使用括号,比如foo $ bar quux而不是foo (bar quux)。我明白了吗?后一种形式被认为是“坏风格”吗?

5 个答案:

答案 0 :(得分:18)

当开始和结束的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中的每个函数应用于列表{{1}}的每个元素。

答案 1 :(得分:6)

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

但请注意:

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

也就是说,$是一个函数;因此,它可以传递给函数,由它组成,以及你想用它做的任何其他事情。我想我之前看到它被人们用组合器拧紧了。

答案 2 :(得分:4)

($)的文档回答了您的问题。不幸的是,它未列在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

答案 3 :(得分:4)

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

  

$ 无法始终替换为括号

但是 $的任何应用都可以使用括号来消除,($)的任何使用都可以被id取代,因为 { {1}}是身份功能的专业化$的使用可以由(f$)替换,但像f这样的用法(将函数作为参数并将其应用于($x))没有任何明显的替代我明白了。

答案 4 :(得分:1)

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

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

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