Совместное использование элементов списка и индексов

Мне всегда было неудобно иметь функцию или выражение, которые требуют использования значений, а также индексов списка (или массива, применяется точно так же) в Haskell.

Я написал validQueens ниже, экспериментируя с проблемой N-ферзей здесь ...

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 повсюду отстой. К тому же, по крайней мере, на первый взгляд, это дороже как во времени, так и в пространстве. Я не уверен, нравится мне это больше или нет.

Короче говоря, я не очень доволен

  1. итерацией по индексу, ограниченному длиной, или, что еще хуже, по одному и по два
  2. Кортежи индексных элементов

Кто-нибудь нашел шаблон более элегантный, чем любой из вышеперечисленных? Если нет, то есть ли веские причины, по которым один из вышеперечисленных методов лучше?

12
задан Community 23 May 2017 в 12:17
поделиться