haskell - liftM2的懒人版

标签 haskell monads lazy-evaluation

回复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/

相关文章:

具有许多构造函数的用于 ADT 的 Haskell Zipper

Haskell Typeclass 速记

haskell - 重复使用导管是否安全?

scala - 等效于 Scala 中的 Haskell do-notation 或 F# 计算表达式?

haskell - OCaml 中的反向状态单子(monad)

haskell - 如何组合这两个函数

haskell - Haskell 中的错误处理与 Either monad

javascript - JS Monad 单元函数

parsing - 应用解析器陷入无限循环

ruby - 如何在 Ruby 中获得惰性数组?