关于haskell:“。”和“$”表达式之间的区别

The difference between “.” and “$” expressions

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Haskell: difference between . (dot) and $ (dollar sign)

我理解"$"将类似"f1(f2 x)"的表达式绑定到更简单的形式"f1$f2 x"。"f1.f2 x"与此有何区别?


那么,f1 . f2 xf1f2 x的组成。你可能是指(f1 . f2) x或相当于f1 . f2 $ x;即应用于xf1f2的组成。

通过查看以下类型可以找到答案:

1
2
($) :: (a -> b) -> a -> b
(.) :: (b -> c) -> (a -> b) -> a -> c

简单地说,($)将一个函数应用于它的参数,1和(.)组成它的两个参数。两条链

1
f . g . h $ x

1
f $ g $ h $ x

是等效的;前者通常是首选的,因为它更容易通过剪切和粘贴将组合重构成自己的函数,但这不是一个通用的首选。视觉噪声也要低一点。

1实际上,($)id相同,它只是返回给定的函数。它只是因为给它的操作符优先级非常低(实际上是最低的),才有用。


($)(.)都没有做什么特别的"绑定表达式"的事情。他们和其他人一样只是操作员。你只需要知道它们是什么定义,它们的固定性是什么。第一:

1
2
3
infixr 0 $

f $ x = f x

所以它是函数应用程序,具有很低的优先级和右关联性。所以,如果你有f x $ g y z,这意味着(f x) (g y z),相当于f x (g y z)。它主要用来避免括号。

第二:

1
2
3
infixr 9 .

(.) f g x = f (g x)

起初看起来很相似,但是(.)操作的是两个函数,而不是一个函数和一个参数,并且具有很高的优先级。所以,如果你有(f x . g y) z,这意味着(f x) ((g y) z),相当于f x (g y z)

关键的区别在于,使用(.),可以将许多函数链接在一起,如f1 . f2 . f3,而使用($),只能对结果应用更多的函数。因此,在像f x $ g y $ h z这样的表达式中,如果决定用一个完整的值列表替换单个值z,就不能只写map (f x $ g y $ h) zs,因为括号表达式中没有要应用的函数。如果您改为编写类似于f x . g y . h $ z的代码,那么您只需删除最后一个函数应用程序并获得map (f x . g y . h) zs,它就可以工作了。