代码之家  ›  专栏  ›  技术社区  ›  titaniumdecoy Mr. T

map与mapM行为

  •  29
  • titaniumdecoy Mr. T  · 技术社区  · 15 年前

    现在我正在尝试理解mapM函数。据我所知,函数“执行”列表中的每个元素,这些元素必须是“action”(IO monad)。

    没有意义的是 this example

    Prelude> map (\x -> [x]) [0, 1, 2]
    [[0],[1],[2]]
    Prelude> mapM (\x -> [x]) [0, 1, 2]
    [[0,1,2]]
    2 回复  |  直到 11 年前
        1
  •  21
  •   sepp2k    15 年前

    这对于IO是正确的,但是在您的代码示例中,您不使用IO monad,而是使用list monad(您给mapM的函数返回一个list)( [x] ),而不是IO)。

    mapM mapM f as = sequence (map f as) . 如果f返回一个IO,这意味着对于列表中的每个元素,它通过将f应用于元素来构造一个IO。然后,它将map返回的IOs列表转换为一个IO,其中包含一个使用sequence的列表(因此,当您执行IO时,会返回一个包含非IO值的列表)。

    对于列表,它意味着它通过应用 f as . 然后使用 sequence sequence [[1,2],[3,4]] 退货 [[1,3],[1,4],[2,3],[2,4]] ).

        2
  •  18
  •   sigfpe    15 年前

    这两个片段不是“类似的”,您不应该期望相关的结果,这一点可能值得澄清。特别是,一个'一元'版本的

    地图(\x->[x] )[0,1,2]

    mapM(\x->返回[x])[0,1,2]

    注意额外的 return .

    return (map f x) 与相同 mapM (return . f) x

    x >>= f “展平”应用的结果 f x . 当你忘了 返回 应用的结果 \x -> [x] 返回 取消额外的展平。

    推荐文章