gpt4 book ai didi

haskell - liftM、lilftA等中首选什么

转载 作者:行者123 更新时间:2023-12-03 14:44:49 27 4
gpt4 key购买 nike

最近我一直在编写在 IO monad 中返回数据结构的 FFI 代码。例如:

peek p = Vec3 <$> (#peek aiVector3D, x) p
<*> (#peek aiVector3D, y) p
<*> (#peek aiVector3D, z) p

现在我可以想到四种编写代码的好方法,它们都密切相关:
peek p = Vec3 <$> io1 <*> io2 <*> io3
peek p = liftA3 Vec3 io1 io2 io3
peek p = return Vec3 `ap` io1 `ap` io2 `ap` io3
peek p = liftM3 Vec3 io1 io2 io3

请注意,我询问的是不需要 Applicative 之外的任何内容的单子(monad)代码。提供。编写此代码的首选方式是什么?我应该使用 Applicative强调代码的作用,或者我应该使用 Monad因为它可能 (?) 对 Applicative 进行了优化?

由于只有 [liftA..liftA3],这个问题稍微复杂了一点。和 [liftM..liftM5]但是我有几条超过三五个成员的记录,所以如果我决定使用 lift{A,M}我失去了一些一致性,因为我必须对较大的记录使用不同的方法。

最佳答案

首先要记住的是,这比它应该的稍微复杂一些——任何 Monad实例应该有一个关联的 Applicative例如,liftMliftA功能一致。因此,这里有两个指导方针:

  • 如果您正在为任何 Monad 编写通用函数, 使用 liftM公司避免与只有 Monad 的其他函数不兼容约束。
  • 如果您正在使用特定的 Monad您知道的实例附带 Applicative例如,使用 Applicative运算符一致地用于您不需要的任何定义或子表达式 Monad操作,但避免漫无目的地混用。

  • Should I use Applicative to emphasize what the code does, or should I use Monad because it might (?) have optimizations over Applicative?



    一般来说,如果有差异,就会反过来。 Applicative仅支持计算的静态“结构”,而 Monad允许嵌入式控制流。考虑列表,例如 - Applicative ,您所能做的就是生成所有可能的组合并转换每个组合——结果元素的数量完全由每个输入中的元素数量决定。与 Monad ,您可以根据输入的元素在每一步生成不同数量的元素,让您可以任意过滤或扩展。

    一个更有效的例子是 ApplicativeMonad基于压缩无限流的实例-- Applicative可以简单地以明显的方式将它们压缩在一起,而 Monad必须重新计算很多东西然后扔掉。

    所以,最后一期是 liftA2 f x yf <$> x <*> y ,或 Monad等价物。我的建议是以下准则:
  • 如果您无论如何都要写出每个参数,请使用中缀形式,因为对于大型表达式来说更容易阅读。
  • 如果您只是提升现有功能,请使用 foo = liftA2 bar而不是 foo x y = bar <$> x <*> y ——它更短,更清楚地表达了你在做什么。

  • 最后,关于一致性问题,您没有理由不能简单地定义自己的 liftA4。等等,如果你需要的话。

    关于haskell - liftM、lilftA等中首选什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9509350/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com