为什么bind(>> =)存在?没有绑定的解决方案难以处理的典型情况是什么?

uin*_*r_t 3 monads haskell

这是绑定方法的类型声明:

(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)

我按如下方式阅读:将一个返回包装值的函数应用于包装值.

此方法作为Monad类型类的一部分包含在Prelude中.这意味着有很多情况需要它.

好的,但我不明白为什么它是典型案例的典型解决方案.

如果您已经创建了一个返回包装值的函数,为什么该函数尚未包含值?

换句话说,有许多函数采用正常值但返回包装值的典型情况是什么?(而不是获取包装值并返回包装值)

Lee*_*Lee 11

值的"展开"正是你在处理monad时想要隐藏的东西,因为这会导致很多样板.

例如,如果您有一系列操作返回Maybe要组合的值,则必须手动传播,Nothing如果收到一个:

nested :: a -> Maybe b
nested x = case f x of
    Nothing -> Nothing
    Just r ->
        case g r of
            Nothing -> Nothing
            Just r' ->
                case h r' of
                    Nothing -> Nothing
                    r'' -> i r''
Run Code Online (Sandbox Code Playgroud)

这就是bind为你做的事情:

Nothing >>= _ = Nothing
Just a >>= f = f a
Run Code Online (Sandbox Code Playgroud)

所以你可以写:

nested x = f x >>= g >>= h >>= i
Run Code Online (Sandbox Code Playgroud)

有些monad根本不允许你手动解压缩值 - 最常见的例子是IO.从a获取值的唯一方法IO是,map或者>>=这两者都要求您在输出中传播IO.