回复another question ,我写的
andM :: (Monad m) => m Boolean -> m Boolean -> m Boolean
andM m1 m2 = do
x <- m1
case x of
True -> m2
False -> return False
如果没有必要,它不会评估m2
,这与liftM2 (&&) m1 m2
(在IO
中)不同。
有没有一种方法可以编写与 liftM2
相同类型的 liftM2Lazy
(或以某种方式受到更多限制?),从而总体上保留惰性?所以例如liftM2Lazy (&&)
与 andM
无法区分,liftM2Lazy (||)
与 orM
(具有明显的定义)等等?
最佳答案
不,这通常是不可能的——它需要源到源的转换才能将惰性函数提升为惰性单子(monad)函数。
特别是对于IO
,以及人们提前知道函数在哪些参数中是惰性的(以及它的惰性有多“深”——也就是说,惰性有多深)到返回的结构中,需要评估以发现是否需要执行另一操作),可以使用 IO 的异常捕获和 unsafeInterleave 功能来编写一个通用提升功能。但这些函数非常具体,而且很容易错误使用,我怀疑您最好根本不编写它们。
关于haskell - liftM2的懒人版,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50783791/