3

我无法在 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

行在 z 中,但是将纯 fb 函数与一元 fa 和 fc 函数结合起来的优雅方式是什么?

4

3 回答 3

7

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

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

在这种特定情况下,您可以做很多事情,但在更一般的情况下可能不起作用。您可以将调用“内联”到fb; 消除绑定/返回对;并使用一元组合而不是do-notation。将这三个都付诸实践将产生

z = fa >=> fc . fb

尽管您可以只选择对您的特定情况来说似乎合理/可读/美观的转换。

于 2015-12-02T18:04:19.160 回答
3

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

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

或者

z a = fa a >>= fc . fb
于 2015-12-02T18:20:18.170 回答
1

用于let非单子绑定:

z :: a -> IO c
z a = do x <- fa a
         let y = fb x
         z <- fc y
         return (z)
于 2015-12-02T18:04:06.623 回答