2012-01-13 93 views

回答

7

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

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

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

简单,($)适用的功能,它的参数,和(.) 它的两个参数。两条链

f . g . h $ x 

f $ g $ h $ x 

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

实际上,($)id等同于身份函数;它只是返回给定的函数。它只是有用的,因为它的运算符优先级很低(实际上是最低的)。

+1

我会说''($)'对于像'map($ 3)[(+5),(* 2),(subtract 4)]' – 2012-01-13 23:52:03

+0

这样的东西也是有用的(或者至少很酷)我以前从来没有想过,但你也可以做'map(\'id \'3)[(+5),(* 2),(subtract 4)]'! :) – Rotsor 2012-01-14 17:04:30

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,它将起作用。