我正在解决haskell Wikibook中的一个问题,完全陷入困境。他们要求“将monad列表中的兔子入侵示例概括为任意几代。”
兔子入侵示例的描述:
“将熟悉的列表处理功能合并到单子代码中很容易。请考虑以下示例:兔子每窝平均要养六个试剂盒,其中一半是雌性的。从单身母亲开始,我们可以对数字进行建模连续几代中雌性试剂盒的数量(即兔子长大并有自己的垫料后新试剂盒的数量):“
Prelude> let generation = replicate 3
Prelude> ["bunny"] >>= generation
["bunny","bunny","bunny"]
Prelude> ["bunny"] >>= generation >>= generation
["bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny"]
我的尝试生成嵌套列表而不是平面列表
本章中提到的我应该使用的功能包括:序列,复制,replicateM,mapM,forM及其下划线版本,它们不会将上下文传递给下一个绑定的monad。
["bunny"] >>= replicateM 2 gen
我知道
[["bunny","bunny","bunny"],["bunny","bunny","bunny"]]
但应该是
["bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny"]
您可以使用nest :: Monad m => Int -> (a -> m a) -> a -> m a
,也可以自己实现。 nest :: Monad m => Int -> (a -> m a) -> a -> m a
使用nest
,并在其中传递“单位”列表foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
:
foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
然后可以使用:
()
请注意,初始值不是nest :: (Monad m) => Int -> (a -> m a) -> a -> m a
nest n f x0 = M.foldM (\x () -> f x) x0 (List.replicate n ())
的列表,而是Prelude Control.Monad.HT> nest 2 generation "bunny"
["bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny"]
本身。
我们可以通过"bunny"
递归来实现一个功能:
"bunny"
然后我们获得:
foldl
我们可以像foldN :: Monad m => Int -> (a -> m a) -> m a -> m a
foldN n x0 = foldl (>>=) x0 . replicate n
一样通过以下方式递归定义:
Prelude Control.Monad> foldN 2 ["bunny"] generation
["bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny","bunny"]