使用Haskell从序列1,2,3,4,5…打印1,5,9,13

使用Haskell从序列1,2,3,4,5…打印1,5,9,13,haskell,Haskell,我必须使用Haskell从自然数列表[1,2,3…]中创建一个每4n+1项的列表 我可以用一些例子来编写这个程序: elem' n xs = case drop (4*n) xs of (y:ys) -> y : elem' n ys [] -> [] 这将生成原始列表中每个第n个元素的列表 但是我的代码没有给出正确的结果。谁能指出哪里出了问题?我是否应该使用drop并执行一些递归?如果您的目标是生成序列1、5、9,…,那么您

我必须使用Haskell从自然数列表[1,2,3…]中创建一个每4n+1项的列表

我可以用一些例子来编写这个程序:

elem' n xs = case drop (4*n) xs of
              (y:ys) -> y : elem' n ys
              [] -> []
这将生成原始列表中每个第n个元素的列表


但是我的代码没有给出正确的结果。谁能指出哪里出了问题?我是否应该使用drop并执行一些递归?

如果您的目标是生成序列1、5、9,…,那么您可以这样写:

[1, 5 .. ]
事实上,这会生成一个如下列表:

Prelude> [1, 5 .. ]
[1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,…
如果您希望获得这些索引处的元素,则可能不需要
n
。这里的n是所谓的“迭代器”,它表示对于每个n,我们访问4×n+1元素,所以每次“跳过”三个元素:

obtain4_1 :: [a] -> [a]
obtain4_1 [] = []
obtain4_1 (x:xs) = x : go xs
    where go (_:_:_:ys) = obtain4_1 ys
          go _ = []
对于项目列表
[1..]
,这为我们提供了相同的值:

Prelude> obtain4_1 [1..]
[1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,181,…

如果您的目标是生成序列1、5、9,…,那么您可以这样写:

[1, 5 .. ]
事实上,这会生成一个如下列表:

Prelude> [1, 5 .. ]
[1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,…
如果您希望获得这些索引处的元素,则可能不需要
n
。这里的n是所谓的“迭代器”,它表示对于每个n,我们访问4×n+1元素,所以每次“跳过”三个元素:

obtain4_1 :: [a] -> [a]
obtain4_1 [] = []
obtain4_1 (x:xs) = x : go xs
    where go (_:_:_:ys) = obtain4_1 ys
          go _ = []
对于项目列表
[1..]
,这为我们提供了相同的值:

Prelude> obtain4_1 [1..]
[1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,181,…
利用haskell,您可以编写如下函数:

obtain :: Int -> Int -> [Int]
obtain 0 _  = []
obtain n x = [ a * x + 1| a<-[0..n] ]
如果需要生成列表的第n个元素,可以为此编写一个帮助函数。

利用haskell,可以编写如下函数:

obtain :: Int -> Int -> [Int]
obtain 0 _  = []
obtain n x = [ a * x + 1| a<-[0..n] ]

如果您需要生成列表的第n个元素,您可以为此编写一个helper函数。

我建议在无限列表上使用递归。像这样的东西应该能奏效

run :: [Int] -> [Int]
run (x:xs) = x : run (drop 3 xs)
请注意,
run
返回一个无限列表,因此您应该只获取有限数量的元素

take 10 $ run [1..]

我建议在无限列表上使用递归。像这样的东西应该能奏效

run :: [Int] -> [Int]
run (x:xs) = x : run (drop 3 xs)
请注意,
run
返回一个无限列表,因此您应该只获取有限数量的元素

take 10 $ run [1..]

为什么要使用
4*n
n
是不是“迭代器”,也就是说索引
1,5,9,13,
…我认为对于4*n,n=1等于4,它将删除前4个元素,并给我第5个元素。但是
4*
是否会出现?另一种方法可以是
映射(+1)。(*4))[0..
如果您有兴趣帮助调试自己的代码,张贴不正确的输出,并猜测为什么会得到正确的结果而不是正确的结果。在试图修复错误之前,尝试了解错误是非常有效的。为什么要使用
4*n
n
是不是“迭代器”,也就是说索引
1,5,9,13,
…我认为对于4*n,n=1等于4,它将删除前4个元素,并给我第5个元素。但是
4*
是否会出现?另一种方法可以是
映射(+1)。(*4))[0..
如果您有兴趣帮助调试自己的代码,张贴不正确的输出,并猜测为什么会得到正确的结果而不是正确的结果。在试图解决问题之前,尝试了解问题是非常有效的。谢谢,这很有效。我想知道是否有可能通过使用一些递归来替换go(:::ys),使其更通用?我们可以提供一个整数n,每三个跳过一次elements@2014GAM:您可以使用
drop
从列表中删除多个元素,从而继续递归列表的其余部分。谢谢,这很有效。我想知道是否有可能通过使用一些递归来替换go(:::ys),使其更通用?我们可以提供一个整数n,每三个跳过一次elements@2014GAM:您可以使用
drop
从列表中删除多个元素,因此,继续对列表的其余部分进行递归。基本上这是@Willem Van onsembasicaly昨天建议的解决方案的实现这是@Willem Van Onsem昨天建议的解决方案的实现