gpt4 book ai didi

haskell - 如何解释函数实例的bind/>>=?

转载 作者:行者123 更新时间:2023-12-04 11:20:48 24 4
gpt4 key购买 nike

我正在努力提高对 Applicative 的理解s 和 Monad s 通过在 Javascript 中实现它们的函数实例。我对 Haskell 的了解有限,我希望我的问题完全有道理。

这是我对 fmap 的实现, <*>>>=对于Functor , ApplicativeMonad Javascript中的类型类:

const fmap = f => g => x => f(g(x)); // B combinator
const apply = f => g => x => f(x) (g(x)); // S combinator
const bind = f => g => x => g(f(x)) (x); // ?

我不确定 bind是 Haskell 实现的正确翻译:
(>>=)  :: (r -> a) -> (a -> (r -> b)) -> r -> b

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

前提是 bind是正确的,它是如何解释的?我知道 Applicative可以对有效的计算进行排序。我也知道 Monad此外,您还可以根据前一个效果的结果确定下一个效果。

我可以看到序列(Javascript 中的急切评估顺序):
  • apply : f(x) ... g(x) ... lambda(result of g) ... lambda 的结果
  • bind : f(x) ... g(result of f) ... lambda(x) ... lambda 的结果

  • 但是, bind功能看起来很奇怪。为什么是 fg反过来嵌套?具体如何 Monad此实现中反射(reflect)的行为(根据前一个效果确定下一个效果)?其实 g(f(x)) (x)看起来像一个带有翻转参数的函数组合,其中 g是二元函数。

    当我申请 apply/ bind使用一元和二元函数,它们产生相同的结果。这没有多大意义。

    最佳答案

    Lee's answer 的一些脚注:

    However, the bind function looks pretty weird. Why are f and g nested the other way around?



    因为 bind是倒退的。比较 (>>=)及其翻转版 (=<<) :
    (>>=) :: Monad m => m a -> (a -> m b) -> m b
    (=<<) :: Monad m => (a -> m b) -> m a -> m b

    或者,在您的具体示例中:
    (>>=) :: (r -> a) -> (a -> (r -> b)) -> (r -> b)
    (=<<) :: (a -> (r -> b)) -> (r -> a) -> (r -> b)

    在实践中,我们倾向于使用 (>>=)多于 (=<<) (因为 (>>=) ,从语法上讲,它非常适合用于构建的管道单子(monad)),从理论的角度来看 (=<<)是最自然的写法。特别是与 fmap 的异同。/ (<$>)(<*>)更明显:
    (<$>) :: Functor f     =>   (a -> b) -> f a -> f b
    (<*>) :: Applicative f => f (a -> b) -> f a -> f b
    (=<<) :: Monad f => (a -> f b) -> f a -> f b

    When I apply apply/bind with an unary and a binary function, they yield the same result. This doesn't make much sense.



    这是关于函数实例的一个偶然事实。让我们并排放置专门的签名:
    (<*>) :: (r -> (a -> b)) -> (r -> a) -> (r -> b)
    (=<<) :: (a -> (r -> b)) -> (r -> a) -> (r -> b)
    Monad超越 Applicative通过提供根据先前结果确定下一个效果的方法(与“以前的效果”相反—— Applicative 已经可以做到这一点)。在这种情况下,效果由一个函数组成,该函数在给定 r 类型的参数的情况下生成值。 .现在,由于可以翻转具有多个参数的函数(即返回函数的函数),因此 (r -> (a -> b)) 之间没有显着差异。和 (a -> (r -> b)) ( flip 可以很容易地将一个更改为另一个),这使得 Monad (->) r 的实例完全等同于 Applicative一。

    关于haskell - 如何解释函数实例的bind/>>=?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40131562/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com