如何在兔子入侵问题中运行任意几代人

问题描述 投票:1回答:1

我正在解决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"]
haskell bind monads applicative replicate
1个回答
1
投票

您可以使用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"]
© www.soinside.com 2019 - 2024. All rights reserved.