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