The function sameDiag is somewhat enigmatic. So I rewrite it as:
queens :: Int -> [[Int]] queens n = filter test (generate n) where generate 0 = [[]] generate k = [q : qs | q <- [1..n], qs <- generate (k-1)] test [] = True test (q:qs) = isSafe q qs && test qs isSafe try qs = not (try `elem` qs || try `elem` zipWith (+) qs [1..] || try `elem` zipWith (-) qs [1..]) -- isSafe try qs = not (try `elem` qs || sameDiag try qs) -- sameDiag try qs = any (\(colDist,q) -> abs (try - q) == colDist) $ zip [1..] qs main = do print $ queens 4
[[2,4,1,3],[3,1,4,2]]
The function zipWith makes a list, its elements are calculated from the function
(+) and the elements of input lists, qs and [1..], occurring at the same position in both lists.
For example:
% ghci GHCi, version 7.10.3 Prelude> [1,3,2,4] [1,3,2,4] Prelude> zip [1,3,2,4][1..] [(1,1),(3,2),(2,3),(4,4)] Prelude> zipWith (+) [1,3,2,4][1..] [2,5,5,8]
The two same numbers, 5, in the obtained list [2,5,5,8] tells you that the queens on (b,3) and (c,2) are in the same diagonal, thus the arrangement [1,3,2,4] should fail the test.