是的,这是ap :: Monad m => m (a -> b) -> m a -> m b的特例
在这里你应该看到 monad m 和 (->) r,所以是一个带参数的函数。现在ap is defined as [source]:
ap m1 m2 = do
x1 <- m1
x2 <- m2
return (x1 x2)
因此这是语法糖:
ap m1 m2 = m1 >>= (\x1 -> m2 >>= return . x1)
绑定函数>>=定义为for a (->) r instance as [source]:
instance Monad ((->) r) where
f >>= k = \ r -> k (f r) r
return = const
(return默认等于pure,定义为const)。
也就是说:
ap f g = f >>= (\x1 -> g >>= const . x1)
= f >>= (\x1 -> (\r -> (const . x1) (g r) r))
= \x -> (\x1 -> (\r -> (const . x1) (g r) r)) (f x) x
现在我们可以执行 beta 缩减(x1 是 (f x)):
ap f g = \x -> (\r -> (const . (f x)) (g r) r) x
还有另一个 beta 减少(r 是 x):
ap f g = \x -> (const . (f x)) (g x) x
我们可以将const 解包为\c _ -> c,将(.) 解包为f . g 到`\z -> f (g z):
ap f g = \x -> ((\c _ -> c) . (f x)) (g x) x
= \x -> (\z -> (\c _ -> c) ((f x) z)) (g x) x
现在我们可以再次执行 beta 缩减(z 是 (g x),c 是 ((f x) (g x))):
ap f g = \x -> ((\c _ -> c) ((f x) (g x))) x
= \x -> (\_ -> ((f x) (g x))) x
最后我们执行 beta 缩减(_ 是 x):
ap f g = \x -> ((f x) (g x))
我们现在将x 移动到函数的头部:
ap f g x = (f x) (g x)
在 Haskell 中,f x y 是 (f x) y 的缩写,因此这意味着:
ap f g x = (f x) (g x)
= f x (g x)
这是请求的函数。