如何重构Haskell列表单子代码?

如何重构Haskell列表单子代码?,haskell,refactoring,monads,Haskell,Refactoring,Monads,我最近发现了与Control.Monad模块(已定义)相关的guard函数,它似乎是解决常见编程难题的完美函数:。我提出了这个解决方案: import Control.Monad(守卫) 类型对a=(a,a) 八皇后::[[Pair Int]] 八皇后=do r1您可以在保留已放置皇后列表的同时递归: place :: Int -> [Pair Int] -> [[Pair Int]] place 9 placed = return placed place n placed = d

我最近发现了与
Control.Monad
模块(已定义)相关的
guard
函数,它似乎是解决常见编程难题的完美函数:。我提出了这个解决方案:

import Control.Monad(守卫)
类型对a=(a,a)
八皇后::[[Pair Int]]
八皇后=do

r1您可以在保留已放置皇后列表的同时递归:

place :: Int -> [Pair Int] -> [[Pair Int]]
place 9 placed = return placed
place n placed = do
   r <- tag n [1..8]
   guard $ all (friendly r) placed
   place (n + 1) (r : placed)

eight_queens :: [[Pair Int]]
eight_queens = place 1 []
place::Int->[Pair Int]->[[Pair Int]]
放置位置9=返回放置位置
放置,放置

r关于保护函数如何影响do块流的任何说明?@NewtonMigosi它的工作原理与您的代码相同<列表monad中的code>guard boolean
生成一个单元素列表
[()]
(当
boolean
为true时)或一个空列表
[]
(否则)。在前一种情况下,do块看到一个元素,选择该元素,并继续使用当前的
r
值。在后者中,do块不能选择元素,因此它丢弃当前的
r
,并阻止块的其余部分运行——在这种情况下没有递归调用。(从技术上讲,这不是do块,而是它被分解成列表monad的
>=
,但这并不重要。)