从我正在阅读的内容来看,$
被描述为“将函数应用于其参数”。但是,它似乎与Lisp中的(apply ...)
完全不同,因为它是一个二元运算符,所以它看起来真的唯一有助于避免使用括号,比如foo $ bar quux
而不是foo (bar quux)
。我明白了吗?后一种形式被认为是“坏风格”吗?
答案 0 :(得分:18)
$
优先于括号。
例如
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),这是与您的问题非常相关的另一个问题。