Я пытаюсь понять, как работает монада Select
. По-видимому, это двоюродный брат Cont
, и его можно использовать для поиска назад.Как использовать монаду Выбрать для решения n-queens?
У меня есть этот список на основе решения проблемы н-королев:
-- All the ways of extracting an element from a list.
oneOf :: [Int] -> [(Int,[Int])]
oneOf [] = []
oneOf (x:xs) = (x,xs) : map (\(y,ys) -> (y,x:ys)) (oneOf xs)
-- Adding a new queen at col x, is it threathened diagonally by any of the
-- existing queens?
safeDiag :: Int -> [Int] -> Bool
safeDiag x xs = all (\(y,i) -> abs (x-y) /= i) (zip xs [1..])
nqueens :: Int -> [[Int]]
nqueens queenCount = go [] [1..queenCount]
where
-- cps = columsn of already positioned queens.
-- fps = columns that are still available
go :: [Int] -> [Int] -> [[Int]]
go cps [] = [cps]
go cps fps = [ps | (p,nfps) <- oneOf fps, ps <- go (p:cps) nfps, safeDiag p cps]
Я изо всех сил, чтобы приспособить это решение использовать Select
вместо.
Кажется, что Select
позволяет вам абстрагироваться от «функции оценки», которая используется для сравнения ответов. Эта функция передается в runSelect
. У меня такое ощущение, что что-то вроде safeDiag
в моем решении может работать как функция оценки, но как структурировать само вычисление Select
?
Кроме того, достаточно ли использовать монаду Select
, или мне нужно использовать версию трансформатора по спискам?
Вы уверены, что хотите выбрать 'Select' monad? Мое понимание «Выбор» заключается в том, что он пытается доказать существование возможного решения (как доказательство свидетельства). Типичным примером 'Select' является SAT-решатель. Вероятно, вы можете заставить что-то сделать с помощью 'SelectT' над монадой списка, но я уверен, что вы действительно будете использовать избранную монаду. – Alec
@Alec Я читал, что 'Select' был хорош для поиска в обратном направлении, а n-queens - это архетипическая проблема такого типа, поэтому я предположил, что это было хорошим вариантом для монады. – danidiaz
Различие может заключаться в обратном отслеживании, чтобы найти все решения и отступить, пока не найдете решение. Опять же, я только играл с 'Select' раньше, так что не принимайте ничего, что я говорю серьезно. – Alec