在monad中绑定一个函数n次

Nir*_*iel 4 haskell

我已经看到使用iteratereplicate为了应用函数n时间的解决方案.但是,我没有设法在州monad中使用它.

此代码有效:

-- Stuff an empty game level with obstacles.
generateLevel :: Level -> State StdGen Level
generateLevel lvl =
    placeRandomWall lvl >>= placeRandomWall >>= placeRandomWall
Run Code Online (Sandbox Code Playgroud)

这个也很有效,不出所料:

generateLevel :: Level -> State StdGen Level
generateLevel lvl =
    placeRandomWall =<< placeRandomWall =<< placeRandomWall lvl
Run Code Online (Sandbox Code Playgroud)

但是,这与以下内容不同:

generateLevel :: Level -> State StdGen Level
generateLevel lvl =
    (placeRandomWall =<< placeRandomWall =<< placeRandomWall) lvl
Run Code Online (Sandbox Code Playgroud)

关于类型的最新抱怨.因此,我不能foldl (=<<) id (relicate 42 placeRandomWall),也不能iterate.

这是有道理的,因为迭代需要一个a -> a函数,而我所拥有的a -> m a或类似的东西.所以,我真的不知道怎么去那里.

Car*_*arl 7

我想你正在寻找<=<>=>来自Control.Monad.它们可以折叠在您replicate创建的列表中,以创建一个重要的操作.

试试foldr (<=<) return (replicate 42 placeRandomWall).

  • @Niriel在这个特殊情况下,foldl和foldr之间确实没有区别.但总的来说,折叠器允许更多的懒惰.所以每当我没有理由使用foldl时,我更喜欢它. (3认同)