我一直觉得在 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
地方有点糟糕。至少乍一看,它在时间和空间上的成本都更高。我不确定我是否更喜欢它。
所以简而言之,我对任何一个都不满意
- 通过以长度为界的索引进行迭代,或者更糟糕的是,逐个和两个
- 索引元素元组
有没有人发现比上述任何一种都更优雅的模式?如果不是,是否有任何令人信服的理由上述方法之一优越?