在 do 符号中混合单子函数和纯函数

Mixing up monadic functions with pure functions in do notation

我无法在 do 表示法中混淆纯函数和单子函数。我觉得我遗漏了一些明显的东西。

比如我得到了这些函数

fa :: a -> IO b
fb :: b -> c
fc :: c -> IO d

z :: a -> IO c
z a = do x <- fa a
         y <- fb x
         z <- fc y
         return z

由于

这不起作用
y <- fb x

line in z,但是将纯 fb 函数与单子 fa 和 fc 函数结合起来的优雅方式是什么?

对非 monadic 绑定使用 let

z :: a -> IO c
z a = do x <- fa a
         let y = fb x
         z <- fc y
         return (z)

可能您可以做出并让它仍然有效的最小改变是:

z a = do x <- fa a
         let y = fb x
         z <- fc y
         return z

在这种特定情况下,您可以做很多事情,但在更一般的情况下可能行不通。您可以 "inline" 调用 fb;消除 bind/return 对;并使用 monadic composition 而不是 do-notation。将所有这三个付诸实践将产生

z = fa >=> fc . fb

尽管您可以只选择看起来 reasonable/readable/aesthetically 适合您的特定情况的转换。

我会这样写这个特定的例子:

z a = do x <- fa a
         fc $ fb x

z a = fa a >>= fc . fb