首页 > 解决方案 > 如何为多个数字制作一个排序的倍数列表?

问题描述

我在完成 Haskell 课程的作业时遇到问题。我已经解决了这个任务的一个部分问题:我必须编写一个函数,它接受一个 Int 并创建一个包含该 Int 的倍数的无限列表。

function :: Int -> [Int]
function d = [d*x | x <- [1..]]

安慰:

ghci> take 10 (function 3)

[3,6,9,12,15,18,21,24,27,30]

在第二个任务中,我必须扩展该函数,以便它接受一个数字列表并将该列表的每个值用作因子(之前的 d)。例如:

ghci> take 10 (function [3, 5])

应该给

[3,5,6,9,10,12,15,18,20,21]

已经尝试过类似的列表理解

function d = [y*x | y <- [1..], x <- d]

但该函数以未排序的形式返回列表:

[3,5,6,10,9,15,12,20,15,25]

我们得到了应该使用 Haskell 的模函数的提示,但我不知道如何准确地进行。你有什么好的建议给我吗?

标签: listhaskell

解决方案


如果你认为d不是一个因素

y = x * d 

但反而

y `mod` d == 0,

然后您可以从列表中获取列表理解[1..]并添加谓词函数,例如:

function ds 
    | null ds   = [1..]
    | otherwise = [ x | x <- [1..], qualifies x ]
    where
      qualifies x = any (==0) $ (flip mod) <$> ds <*> [x]

一个更具表现力的版本,一开始可能更容易掌握:

function' ds   
    | null ds   = [1..]
    | otherwise = [ x | x <- [1..], divByAnyIn ds x ]
    where
      divByAnyIn ds x = 
          case ds of
            (d:ds') -> if x `mod` d == 0 then True 
                                         else divByAnyIn ds' x
            _       -> False

推荐阅读