函数组合 (.) 如何从内部工作?

How does function composition (.) work from within?

我正在学习Haskell。目前,我正在研究函数组合。我了解(至少在基本层面上)如何使用函数 (.),但有两件事我不明白。

所以函数如下所示:

(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)

首先,类型声明。 (b -> c) -> (a -> b) 本质上意味着函数 f 从函数 g(取值 a)和 returns 的结果值 (b) 中获取参数c 类型的值。下面的-> a -> c我没看懂,为什么要有-> a呢?为什么 (b -> c) -> (a -> b) -> c 错了?从我的角度来看(这显然是错误的),函数 g 已经将 a 作为参数。

其次,函数体f . g = \x -> f (g x)\x -> 在这里做什么? Lambda 非常简单。例如 filter (\(a,b) -> a + b > 4) [(1,2),(3,4)],但是一个简单的 \x -> 让我卡住了。我可能会这样写正文f . (g x) = f (g x)(这显然又是错误的)。

(b -> c) -> (a -> b) -> c 将是一个接受两个函数 f :: b -> cg :: a -> b 的函数,并以某种方式调用 g 而没有 a 类型的初始参数。

对于第二个问题,请考虑如何使用前缀表示法来定义 (.)。 (如果我们为函数使用 "regular" 名称可能会更容易看出;我会将其作为注释包含在每个代码片段之后):

(.) f g x = f (g x)    -- compose f g x = f (g x)

x(.) 的 "third argument",或者更准确地说是 (.) f g 编辑的函数 return 的参数。这相当于直接将 (.) f g 定义为函数,将函数放在右侧而不是该函数的最终 return 值:

(.) f g x =       f (g x)  -- Implicit function def: compose f g x =       f (g x)
(.) f g   = \x -> f (g x)  -- Explicit function def: compose f g   = \x -> f (g x)

您也可以使用括号来隐式定义函数:

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