我在Hoogle上找不到任何内容,但有一个标准函数或运算符,其签名如下:
func :: (a -> b -> c) -> (a -> b) -> a -> c
即。给定两个函数f
和g
以及一个元素x
作为参数计算f x (g x)
?
答案 0 :(得分:10)
您正在寻找的功能是(<*>)
。为什么?嗯,(<*>)
确实有一个更通用的类型:
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
但请注意,我们可以将f
专门化为(->) r
,其中有一个Applicative
个实例:
(<*>) :: (->) r (a -> b) -> (->) r a -> (->) r b
...然后我们可以重新排列类型,因此->
是中缀而不是前缀,通常是:
(<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)
...这与您的签名模数字母重命名相同。
这是有效的,因为函数类型(->)
包含Functor
,Applicative
和Monad
的实例,这些实例被称为“reader”。这些实例为所有参数设置了一个额外的参数,这正是你的函数所做的。
答案 1 :(得分:9)
f <*> g
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
答案 2 :(得分:2)
是的,这是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 - &gt; 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)
这是请求的功能。