浏览列表中的所有项目

时间:2017-11-21 13:07:33

标签: list haskell

此功能的结果:

list = [x*x | x <- [0..100]]    
res = id
    . filter (\(x,y,sum) -> sum > 9)
    . takeWhile (\(x,y,sum) -> sum < 100)
    . nub
    $ [(x, y, (sqrt (x) + sqrt (y))) | x <- list, y <- list]

是[(0,100,10),(0,121,11 ......(0,9801,99)]。 如何使其与x列表中的其他项目一起使用?

2 个答案:

答案 0 :(得分:3)

takeWhile :: (a -> Bool) -> [a] -> [a]是一个函数 - 就像名字所说的那样 - 在条件成立时使用元素。从一个这样的元素失败的那一刻开始,无论是否产生有价值的数据,都不会再发出列表的其余部分。

由于您的list有限,并且您对所有配置感兴趣,因此您不必在此使用takeWhile,您可以使用filter,因此:

res = id
    . filter (\(x,y,sum) -> sum > 9)
    . filter (\(x,y,sum) -> sum < 100)
    . nub
    $ [(x, y, (sqrt (x) + sqrt (y))) | x <- list, y <- list]

现在我们已经解决了这个问题。但是代码仍然有一些冗余和不优雅的方面。

我们最好避免计算平方根,修改list以与原始值一起发射方块。此外,我们可以简单地使它成为无限列表,如果我们想在代码的其他部分重用它,通常会更好:

squares = [ (x, x*x) | x <- [0..]] 

接下来,只要值平方根小于100,我们就会取值:

   where sq100 = takeWhile (\(r,_) -> r < 100) squares

现在我们可以使用列表推导,它取两个列表的平方根和平方并计算平方根的总和,这样总和大于9且小于100.我们可以这样写:

res = [ (x,y,sqq) | (sqx,x) <- sq100, (sqy,y) <- sq100, x <= y,
                    let sqq = sqx+sqy, sqq > 9, sqq < 100 ]
     where sq100 = takeWhile (\(r,_) -> r < 100) squares

我们在此处采用x的{​​{1}}和平方根sqx,我们采用x的{​​{1}}和平方根y ,然后我们约束sqy删除重复项,计算平方根y的总和,最后我们检查该总和是否大于9且小于100。

这会产生2520个结果。

答案 1 :(得分:2)

takeWhile是罪魁祸首,因为总和将是&gt;在某些时候100,然后列表被切断。