Мне всегда было неудобно иметь функцию или выражение, которое требует использования значений, а также индексов, списка (или массива, применяется одинаково) в Haskell.
Я написал validQueens
ниже, экспериментируя с проблемой N-queens здесь...
validQueens x =
and [abs (x!!i - x!!j) /= j-i | i<-[0..length x - 2], j<-[i+1..length x - 1]]
Мне не нравилось использование индексации, все плюсы и минусы и т.д. Это кажется неряшливым. Я придумал следующее:
enumerate x = zip [0..length x - 1] x
validQueens' :: [Int] -> Bool
validQueens' x = and [abs (snd j - snd i) /= fst j - fst i | i<-l, j<-l, fst j > fst i]
where l = enumerate x
вдохновляется Python enumerate
(а не то, что заимствование императивных концепций обязательно является отличной идеей). Кажется, лучше в концепции, но snd
и fst
повсюду отвратительно. Это также, по крайней мере, на первый взгляд, дорогостоящее как во времени, так и в пространстве. Я не уверен, нравится мне это или нет.
Короче говоря, я не очень доволен тем, что
- Итерация по индексу, ограниченному длинами, или, что еще хуже, простыми и двойными
- Корзины индексных элементов
Кто-нибудь нашел образец, который они находят более элегантным, чем любой из вышеперечисленных? Если нет, есть ли какие-либо веские причины, один из вышеперечисленных методов превосходит?