简体   繁体   English

是否有一个计算`fx(gx)`的标准函数?

[英]Is there a standard function that computes `f x (g x)`?

I couldn't find anything on Hoogle, but is there a standard function or operator with a signature like: 我在Hoogle上找不到任何东西,但有一个标准函数或运算符,其签名如下:

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

Ie given two functions f and g and an element x as arguments it computes fx (gx) ? 即给出两个函数fg以及一个元素x作为参数,它计算fx (gx)

The function you're looking for is (<*>) . 您正在寻找的功能是(<*>) Why? 为什么? Well, it's true that (<*>) has a more general type: 嗯, (<*>)有一个更通用的类型:

(<*>) :: Applicative f => f (a -> b) -> f a -> f b

But consider that we can specialize f to (->) r , which has an Applicative instance: 但是考虑到我们可以将f专门化为(->) r ,它有一个Applicative实例:

(<*>) :: (->) r (a -> b) -> (->) r a -> (->) r b

…then we can rearrange the type so -> is infix instead of prefix, as it normally is: ...然后我们可以重新排列类型->是中缀而不是前缀,因为它通常是:

(<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)

…which is the same as your signature modulo alpha renaming. ...这与您的签名模数字母重命名相同。

This works because the function type, (->) , has instances of Functor , Applicative , and Monad , which are idiomatically called “reader”. 这是因为函数类型(->)具有FunctorApplicativeMonad实例,它们被惯用地称为“reader”。 These instances thread an extra argument around to all their arguments, which is exactly what your function does. 这些实例为所有参数设置了一个额外的参数,这正是你的函数所做的。

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

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

Yes, this is a special case of ap :: Monad m => m (a -> b) -> ma -> mb 是的,这是ap :: Monad m => m (a -> b) -> ma -> mb的特例

Here you should see the monad m as (->) r , so a function with a parameter. 在这里你应该看到monad m(->) r ,所以带有参数的函数。 Now ap is defined as [source] : 现在ap定义为[source]

ap m1 m2 = do
    x1 <- m1
    x2 <- m2
    return (x1 x2)

Which is thus syntactical sugar for: 因此,这是语法糖:

ap m1 m2 = m1 >>= (\x1 -> m2 >>= return . x1)

The bind function >>= is defined for a (->) r instance as [source] : 绑定函数>>=被定义(->) r实例为[source]

instance Monad ((->) r) where
    f >>= k = \ r -> k (f r) r
    return = const

( return is by default equal to pure , which is defined as const ). (默认情况下return等于pure ,定义为const )。

So that means that: 这意味着:

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

now we can perform a beta reduction ( x1 is (fx) ): 现在我们可以执行beta减少( x1(fx) ):

ap f g = \x -> (\r -> (const . (f x)) (g r) r) x

and another beta reduction ( r is x ): 和另一个beta减少( rx ):

ap f g = \x -> (const . (f x)) (g x) x

We can unwrap the const as \\c _ -> c , and (.) as f . g 我们可以将const\\c _ -> c ,将(.)f . g f . g to `\\z -> f (gz): f . g到`\\ z - > f(gz):

ap f g = \x -> ((\c _ -> c) . (f x)) (g x) x
       = \x -> (\z -> (\c _ -> c) ((f x) z)) (g x) x

Now we can again perform a beta reductions ( z is (gx) , and c is ((fx) (gx)) ): 现在我们可以再次执行beta减少( z(gx)c((fx) (gx)) ):

ap f g = \x -> ((\c _ -> c) ((f x) (g x))) x
       = \x -> (\_ -> ((f x) (g x))) x

finally we perform a beta-reduction ( _ is x ): 最后我们执行beta减少( _x ):

ap f g = \x -> ((f x) (g x))

We now move x to the head of the function: 我们现在将x移动到函数的头部:

ap f g x = (f x) (g x)

and in Haskell fxy is short for (fx) y , so that means that: 在Haskell中, fxy(fx) y缩写,因此这意味着:

ap f g x = (f x) (g x)
         = f x (g x)

which is the requested function. 这是请求的功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM