是否有一个标准函数来计算`f x(g x)`?

时间:2017-12-12 19:03:52

标签: haskell

我在Hoogle上找不到任何内容,但有一个标准函数或运算符,其签名如下:

func :: (a -> b -> c) -> (a -> b) -> a -> c

即。给定两个函数fg以及一个元素x作为参数计算f x (g x)

3 个答案:

答案 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)

...这与您的签名模数字母重命名相同。

这是有效的,因为函数类型(->)包含FunctorApplicativeMonad的实例,这些实例被称为“reader”。这些实例为所有参数设置了一个额外的参数,这正是你的函数所做的。

答案 1 :(得分:9)

f <*> g⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

请参阅https://wiki.haskell.org/Pointfree

答案 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 缩减(rx):

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)

这是请求的功能。