Haskell 自己的复制项实现
我想知道是否可以为Bool编写自己的replicItem实现Haskell 自己的复制项实现,haskell,Haskell,我想知道是否可以为Bool编写自己的replicItem实现 没有导入Monad模块的值?当我查看Haskell源代码时,它看起来确实很复杂,但我想知道该函数是如何工作的,它应该是什么样子。实现replicateM的一种方法是: replicateM n = sequence . replicate n 这有助于你的理解吗?当然,棘手的部分在于序列的操作,它有以下有趣的类型: sequence :: Monad m => [m a] -> m [a] 因此, replicateM
没有导入Monad模块的值?当我查看Haskell源代码时,它看起来确实很复杂,但我想知道该函数是如何工作的,它应该是什么样子。实现
replicateM
的一种方法是:
replicateM n = sequence . replicate n
这有助于你的理解吗?当然,棘手的部分在于序列的操作,它有以下有趣的类型:
sequence :: Monad m => [m a] -> m [a]
因此,
replicateM 3 (Just 1)
= sequence (replicate 3 (Just 1))
= sequence ([Just 1, Just 1, Just 1])
= Just [1,1,1]
replicItem
的定义是:
replicateM n x = sequence (replicate n x)
Monad m => [m a] -> m [a]
sequence ms = foldr k (return []) ms
where
k m m' = do { x <- m; xs <- m'; return (x:xs) }
而replicate
具有类型Int->a->[a]
,因此,例如replicate 4 True
就是[True,True,True,True]
对于列表参数l=[True,False]
,replicate 2 l
是[[True,False],[True,False]
。您的评论询问replicate
和replicateM
之间有什么不同,您可以看到replicateM
使用replicate
,但随后对结果调用sequence
序列的类型为:
replicateM n x = sequence (replicate n x)
Monad m => [m a] -> m [a]
sequence ms = foldr k (return []) ms
where
k m m' = do { x <- m; xs <- m'; return (x:xs) }
在本例中,m
是列表,因此它将列表列表转换为另一个列表列表。
正如您所指出的,结果不同于调用replicate 2l
。序列的定义是:
replicateM n x = sequence (replicate n x)
Monad m => [m a] -> m [a]
sequence ms = foldr k (return []) ms
where
k m m' = do { x <- m; xs <- m'; return (x:xs) }
它是笛卡尔积,即,通过考虑累加器中每个列表前面的m
元素,形成一个新列表
考虑列表的一种方法是对非确定性选择进行建模,因此结果是输入列表中n
选择的所有可能结果。我不是假装回答这个问题,但注释中缺少格式迫使我回答。
简短版本为
replicateM n m
相当于
m >>= (\x1 -> m >>= (\x2 -> ... m >>= ( \xn -> return [x1,x2,...,xn])..))
或类似
do
x1 <- m
x2 <- m
...
xn <- m
return [x1,x2,...,xn]
do
x1Bool
不是单子,所以您可以使用replicate
。但是replicatem2[True,False]
返回的内容与replicate 2[True,False]返回的内容不一样。
我不确定我是否理解问题陈述。你能清楚地说明为什么有一个“复杂”的实现对你来说是个问题,并且我们可以考虑什么样的标准来提供一个不那么复杂的替代实现。我们已经解决了您的问题?很简单-我只想知道它是如何工作的,因为我不清楚在replicateM
中发生了什么,我很高兴看到它应该如何实现。我相信这会帮助我理解整个过程。我想你实际上很难理解单子列表。因为replicitem 2[True,False]
正在列表monad中工作。列表中包含的Bool
s在这里真的不相关>“当然,棘手的部分在于序列的操作,它有以下有趣的类型”我相信这个函数也没有那么棘手:它就像foldr1>>