Search code examples
haskellintervals

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)]

So far, I've managed to write some cases, but they didn't do the job very well.

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]

Solution

  • Naming is important. When learning, naming is very important.

    What is x? What is y? What is z? Are all of them the same, conceptually?

    No, as the exercise describes it, it is

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

    this already gets you half way there towards the solution. Yes it does.

    Or actually, you have a contradiction. According to the title of your post, it is

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

    But in any case, solving the first one first, you seem to get lost in the multitude of tests. Instead of doing all of them in one function, why not do a test to decide which of several functions to use to do the job; then write each of those functions being already able to assume certain things, namely those which we've tested for:

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

    and now it is easy to see which test to perform here, isn't it?

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

    and similarly here.

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

    I hope this helps you manage this complexity so you'll be able to complete this code yourself.