【问题标题】:Is there a standard function that computes `f x (g x)`?是否有计算“f x (g x)”的标准函数?
【发布时间】:2017-12-13 04:10:33
【问题描述】:

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

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

即给定两个函数 fg 和一个元素 x 作为参数,它计算 f x (g x)?

【问题讨论】:

  • 您可能还想查看combinator S,它在Haskell 中由(<*>) 概括。

标签: haskell


【解决方案1】:

您要查找的函数是(<*>)。为什么?嗯,确实(<*>)有一个更通用的类型:

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

但考虑到我们可以将f 专门化为(-&gt;) r,它有一个Applicative 实例:

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

...然后我们可以重新排列类型,使-&gt; 是中缀而不是前缀,因为它通常是:

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

...这与您的签名模 alpha 重命名相同。

之所以有效,是因为函数类型(-&gt;) 具有FunctorApplicativeMonad 的实例,它们通常被称为“阅读器”。这些实例将一个额外的参数传递给它们的所有参数,这正是您的函数所做的。

【讨论】:

    【解决方案2】:

    f &lt;*&gt; g⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

    https://wiki.haskell.org/Pointfree

    【讨论】:

    • 哦,是的!谢谢。我自己应该知道的。
    【解决方案3】:

    是的,这是ap :: Monad m =&gt; m (a -&gt; b) -&gt; m a -&gt; m b的特例

    在这里你应该看到 monad m(-&gt;) 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)
    

    绑定函数&gt;&gt;=定义为for a (-&gt;) 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 _ -&gt; 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)
    

    这是请求的函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-16
      • 2021-09-25
      • 2017-04-14
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多