sep*_*p2k 20
据我所知,函数"执行"列表中的每个元素必须是"动作"(IO monad).
对于IO来说也是如此,但是在你的代码示例中你不使用IO monad,你使用list monad(你给mapM的函数返回一个list([x]),而不是IO).
mapM被定义为mapM f as = sequence (map f as).如果f返回IO,则意味着对于列表中的每个元素,它通过将f应用于元素来构造IO.然后它将使用序列将映射返回的IO列表转换为包含"列表"的IO(因此,当您执行IO时,将返回包含非IO值的列表).
对于列表,它意味着它通过应用于f每个元素来创建列表列表as.然后,它sequence用于创建列表列表,其中包含在列表列表中获取每个列表的一个元素的所有可能方法(例如,sequence [[1,2],[3,4]]返回[[1,3],[1,4],[2,3],[2,4]]).
sig*_*fpe 15
可能值得明确的是,这两个片段不是"类似的",你不应该期待相关的结果.特别是'monadic'版本
map(\ x - > [x])[0,1,2]
是
mapM(\ x - > return [x])[0,1,2]
请注意额外的return.
一般来说,return (map f x)是一样的mapM (return . f) x.
这是因为名单单子,x >>= f"变平"申请的结果f来x.当你遗漏时return,申请的结果\x -> [x]被平铺到结果中.有一个额外的return取消额外的扁平化.