quux (['0'..9'] ++ ['A'..F']) 2生成长度为2的十六进制数(带有前导零),但显然可以生成任何基和任意长度。
quux digits length = iterate foo return !! length $ [] where
foo bb aa = map (: aa) digits >>= bb这段代码是否可以简化,同时保留在列表中迭代的想法呢?
发布于 2014-11-28 18:40:49
事实证明,这正是replicateM在[] monad中所做的。为了完整起见,让我们来看看replicateM到底是如何工作的。
replicateM :: Monad m => Int -> m a -> m [a]
replicateM n x = sequence (replicate n x)
replicate :: Int -> a -> [a]
replicate n x = [ x | _ <- [1..n] ]replicateM原来只是把繁重的工作交给了replicate和sequence。replicate非常简单,因此有趣的部分依次发生:
sequence :: Monad m => [m a] -> m [a]
sequence [] = return []
sequence (x:xs) = do
x' <- x
xs' <- sequence xs
return (x' : xs')事实上,这正是依赖于[] monad实例进行迭代的原因。几个绑定和一个返回。
https://codereview.stackexchange.com/questions/71046
复制相似问题