我无法在符号内混合使用纯函数和monadic函数。我有一种感觉,我错过了一些明显的东西。
例如,假设我有这些功能
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函数与monadic fa和fc函数结合起来的优雅方法是什么?
答案 0 :(得分:7)
您可以做出的最小改变可能仍然有效:
z a = do x <- fa a
let y = fb x
z <- fc y
return z
在这种特定情况下,您可以做很多事情,在更一般的情况下可能无效。您可以“内联”对fb
的通话;消除绑定/返回对;并使用monadic组合而不是do-notation。将所有这三个付诸实践将产生
z = fa >=> fc . fb
尽管您可以选择对您的特定情况看起来合理/可读/美观的转换。
答案 1 :(得分:2)
我这样写下这个特例:
z a = do x <- fa a
fc $ fb x
或
z a = fa a >>= fc . fb
答案 2 :(得分:1)
使用let
进行非monadic绑定:
z :: a -> IO c
z a = do x <- fa a
let y = fb x
z <- fc y
return (z)