You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何遍历单子(Monad)值列表,实现任意长度列表的对应单子操作?

实现方案

你需要的是Monad(更准确说是Applicative)的遍历能力,核心是把包含多个MyMonad值的列表,转换成单个包裹了Int列表的MyMonad值,一行即可实现:

-- 简洁写法
traverse funcReturningMyMonad es >>= funcTakingListOfInts

-- 等价的do语法写法
do
  vs <- traverse funcReturningMyMonad es
  funcTakingListOfInts vs

原理解释

  1. traverse的特化类型完全适配你的场景:
    traverse :: (MyMonad Int -> MyMonad Int) -> [MyMonad Int] -> MyMonad [Int]
    
    它会自动遍历输入列表的所有元素,逐个应用funcReturningMyMonad,最后把所有执行结果打包成一个MyMonad包裹的Int列表,不需要手动按索引取元素,天然支持任意长度的输入列表。
  2. 之后通过>>=把得到的MyMonad [Int]里的列表提取出来,传入funcTakingListOfInts即可,和你手写固定长度的do块逻辑完全等价。
  3. 如果你用的是较老的Haskell标准,也可以用mapM替代traverse,两者在这个场景下效果完全一致。

为什么之前直接用>>=不生效

>>=是单个Monad值的绑定运算符,直接作用在列表上时默认操作的是列表自带的Monad实例,而非你自定义的MyMonad,执行逻辑和预期完全不同,所以得不到正确结果。

内容的提问来源于stack exchange,提问作者That Guy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 20:06:03