编写一个函数,按 k 步列出从 n 到 m 的数字。如果步长是负数,则按降序排列

Write a function that lists numbers from n to m by k number of steps. If the step size is negative list them in descending order

Implement the interval2 :: Int -> Int -> Int -> [Int] function,that lists numbers from the first parameter to the third parameter, the stepping's size is the second parameter. Using [n..m], [n,k..m] or [n..] is prohibited.

For example:

interval2 1 1 10 == [1,2..10]
interval2 10 1 0 == [10,11..0]
interval2 10 (-1) 0 == [10,9..0]
interval2 1 2 10 == [1,3..10]
interval2 10 2 0 == [10,12..0]
interval2 0 (-2) (-10) == [0,(-2)..(-10)]
interval2 1 (-1) 10 == [1,0..10]
interval2 0 (-10) (-1000) == [0,(-10)..(-1000)]

到目前为止,我写了一些案例,但他们做得不是很好。

interval2 x y z | x < z && y > 0 = [x] ++ interval2 (x+y) y z
                | x < z && y < 0 = [x] ++ interval2 (x-y) y z
                | x > z && y > 0 = [x] ++ interval2 (x-y) y z
                | x > z && y < 0 = [x] ++ interval2 (x+y) y z
                | x == z || x > z = [z]

基本上在两种情况下你应该发出一个新值:

  1. 如果x <= zy > 0;和
  2. 如果 x >= zy < 0

在这两种情况下,这意味着列表包含 x 作为第一个元素,并且应该在 x+y 的间隔上递归。如果不满足这些条件中的 none 个,那么我们就到达了列表的末尾。

这意味着该函数看起来像:

interval2 x y z
    | (x <= z && y > 0) || (x >= z && y < 0) = …
    | otherwise = …

我将实施 作为练习。

命名很重要。学习的时候,命名非常重要。

什么是x?什么是 yz 是什么?从概念上讲,它们都是一样的吗?

不,正如练习所描述的那样,它是

interval2 :: Int -> Int -> Int -> [Int]
interval2 from stepSize to = 

这已经让您在解决问题的道路上走了一半。是的。

或者实际上,你有一个矛盾。根据你的标题post,是

interval2b :: Int -> Int -> Int -> [Int]
interval2b from numSteps to = 

但无论如何,先解决第一个问题,您似乎会迷失在众多测试中。与其在一个函数中完成所有这些,不如做一个测试来决定 几个函数中的哪个 来完成这项工作;然后编写这些函数中的每一个,这些函数已经能够假设某些事情,即我们已经测试过的事情:

interval2 from stepSize to 
   | stepSize > 0 = increasing from 
   | stepSize < 0 = decreasing from 
   | otherwise    = []
  where
  increasing from 
    | from 

现在很容易看出要执行哪个测试,不是吗?

            > to = []
    | otherwise  = from : increasing ....
  decreasing from
    | from

这里也是如此。

              .........
     ..................

我希望这可以帮助您管理这种复杂性,以便您能够自己完成此代码。