自己的replicateM实现

bar*_*kmp -1 haskell

我想知道是否可以在 不导入 Monad 模块的情况下为Bool值编写自己的replicateM实现?当我查看 Haskell 源代码时,它看起来确实很复杂,但我想知道该函数如何工作以及它应该是什么样子。

Lee*_*Lee 5

的定义replicateM是:

replicateM n x = sequence (replicate n x)
Run Code Online (Sandbox Code Playgroud)

并且replicate有类型Int -> a -> [a],例如replicate 4 True[True, True, True, True]

对于列表参数l = [True, False]replicate 2 l[[True, False], [True, False]]。您的评论询问replicateand之间有什么不同replicateM,您可以看到replicateM使用replicate但然后调用sequence结果。

的类型sequence是:

Monad m => [m a] -> m [a]
Run Code Online (Sandbox Code Playgroud)

在此示例中,m是列表,因此它将列表列表转换为另一个列表列表。正如您所指出的,结果与调用replicate 2 l. 的定义sequence是:

sequence ms = foldr k (return []) ms
            where
              k m m' = do { x <- m; xs <- m'; return (x:xs) }
Run Code Online (Sandbox Code Playgroud)

do系列表块就像下面的列表理解:

[[x:xs] | x <- m, xs <- m']
Run Code Online (Sandbox Code Playgroud)

这是一个笛卡尔积,即通过m对累加器中每个列表前面的每个元素进行 consing 来形成一个新列表。

考虑列表的一种方法是对非确定性选择进行建模,因此结果是n输入列表中选择的所有可能结果。