我知道点(.)运算符被定义为接受三个参数(两个函数和“Num”类中约束的“a”类型的值),并通过将参数应用于右侧的函数来工作,并将左侧的函数应用于左侧应用程序的输出,如下所示:
-- Associativity: infixr 9
(.) :: (b -> c) -> (a -> b) -> a -> c
(f . g) x = f(g x)
-- Or in another format
f . g = \x -> f(g x)
现在,这就是在函数组合中使用点运算符的多个应用程序令人困惑的地方,请考虑这一点:
使用像 (+) 这样的中缀运算符,它需要两个“Num”类中类型的参数。
(+) :: Num a => a -> a -> a
-- An application would look like this:
> 4 + 3
7
-- With more applications composed with (+)
> 4 + 3 + 2
9
-- Which is fine, since the last application still takes the legitimate type,
-- which is a value of type within "Num" class, as follows
> (4 + 3) + 2
-- 7 + 3
9
但是使用点运算符,如下所示。最后一个带有点运算符的函数组合应该采用应用程序“(reverse . take 3 $map (*2) [1..]”的输出,即前一个函数的“[6,4,2]”组成。
如果正如我所说,点运算符接受一个值而不是函数和右侧的值,那么它应该如何工作?
> replicate 4 . reverse . take 3 $ map (*2) [1..]
[[6,4,2],[6,4,2],[6,4,2],[6,4,2]]
-- Isn't it supposed to be like follows for its middle step?
-- replicate 4 . [6,4,2]
为什么?
replicate 4 . reverse . take 3 $ map (*2) [1..]
解析为
(replicate 4 . reverse . take 3) $ map (*2) [1..]
因为
($)
的优先级低于 (.)
。所以 (.)
只接受函数作为参数。