Haskell 我应该在什么时候使用$(是否总是可以用括号替换)?
从我所读的内容来看,Haskell 我应该在什么时候使用$(是否总是可以用括号替换)?,haskell,syntax,operators,Haskell,Syntax,Operators,从我所读的内容来看,$被描述为“将函数应用于其参数”。然而,它似乎不像Lisp中的(apply…),因为它是一个二进制运算符,所以它看起来唯一的作用是有时帮助避免使用括号,比如foo$bar-qux,而不是foo(bar-quux)。我理解对了吗?后一种形式被认为是“糟糕的风格”吗?你基本上理解对了——也就是说,大约99%的$Is的使用有助于避免使用括号,是的,在大多数情况下,它似乎比括号更受欢迎 但请注意: > :t ($) ($) :: (a -> b) -> a -> b >:t(元
$
被描述为“将函数应用于其参数”。然而,它似乎不像Lisp中的(apply…
),因为它是一个二进制运算符,所以它看起来唯一的作用是有时帮助避免使用括号,比如foo$bar-qux
,而不是foo(bar-quux)
。我理解对了吗?后一种形式被认为是“糟糕的风格”吗?你基本上理解对了——也就是说,大约99%的$Is的使用有助于避免使用括号,是的,在大多数情况下,它似乎比括号更受欢迎
但请注意:
> :t ($)
($) :: (a -> b) -> a -> b
>:t(元)
($):(a->b)->a->b
也就是说,$是一个函数;因此,它可以传递给函数、由它组成的函数以及任何你想用它来做的事情。我想我以前见过人们用组合词来使用它。
$
如果开头和结尾之间的距离大于良好的可读性,则首选括号y认股权证,或者如果有多层嵌套括号
比如说
i (h (g (f x)))
可以重写
i $ h $ g $ f x
换句话说,它表示右关联函数应用程序。这很有用,因为普通函数应用程序与左关联,即
i h g f x
…可以重写如下
(((i h) g) f) x
($)
函数的其他便捷用法包括使用它压缩列表:
zipWith ($) fs xs
这将函数列表中的每个函数应用于列表中相应的参数,并在列表中收集结果。与序列fs x相比,序列fs x将函数列表应用于单个参数x
,并收集结果;fs xs
应用于将列表fs
中的每个函数添加到列表的每个元素xs
($)的文档回答了您的问题。不幸的是,列表中没有列出它
但是,它列在您可以在此处找到的源代码中:
但是,此模块不直接定义($)。由前者导入的以下内容有:
我将相关代码包括在下面:
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
)我看到没有任何明显的替代品。如果我看一下你的问题和这里的答案,Apocalisp和你都是对的:
- 在某些情况下,
优于括号(见他的答案)$
绝对是不错的风格foo(bar-qux)
另外,请查看另一个与您的问题非常相关的SO问题。关于$signs的菊花链的一个有用的观点是,它可以像Unix管道一样读取,只从右向左。它可以像那样读取“一点”,这就是为什么最好不要这样想。($x)很容易被(\f->f x)代替