和...之间的不同 ”。”和“$”表达式

时间:2012-01-13 23:41:11

标签: haskell

  

可能重复:
  Haskell: difference between . (dot) and $ (dollar sign)

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

2 个答案:

答案 0 :(得分:7)

嗯,f1 . f2 xf1f2 x的组合。您可能意为(f1 . f2) x或等同于f1 . f2 $ x;即f1f2的组成,适用于x

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

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

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

f . g . h $ x

f $ g $ h $ x

是等价的;前者通常是首选,因为使用剪切和粘贴更容易将组合物重构为其自身的功能,但这不是普遍的偏好。它的视觉噪音也有点低。

1 的确,($)与身份函数id相同;它只返回它给出的函数。它只是有用的,因为给它的运算符优先级非常低(实际上是最低的)。

答案 1 :(得分:6)

($)(.)都没有为“绑定表达式”做任何特别的事情。他们只是像其他人一样的运营商。您需要知道的只是它们的定义,以及它们的固定性。第一个:

infixr 0 $

f $ x = f x

所以它是功能应用程序,具有非常低的优先级和右关联性。因此,如果您有f x $ g y z,则表示(f x) (g y z)等同于f x (g y z)。它主要用于避免使用括号。

第二个:

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即可。