Search code examples
listhaskelldivider

Haskell check if function returned same value twice


I'm working on a project and arrived at interesting issue. I have a function let's call it foo this function divides a given number by highest possible divider but not by iteself. If the highest divider is 1 then it returns the given number. For example number 21 first divides by 7 and returns 3 + it keeps returning 3 as there is no other divider other than 3 and 1.

ghci> foo 21
3
foo it
3

Now I want to save these steps taken into function that returns all steps in array. The current implementation is:

bar:: int-> [int]
bar x = x : bar (foo x)

The problem with this method is that it keeps returning the same value and never ends. Is there a way to check if the previous iteration of foo returned the same number and stop so it wouldn't result in infinite list?

Something like:

bar 21
[3]
instead of:
bar 21
[3,3,3,3,3,3,3,3,3...]

In oop i would save last value into var and then compare it, however that's not case in haskell and I'm not sure how else it coulld be achieved


Solution

  • You should check if x is equal to foo x, if that is the case, we can stop the recursion, so:

    bar :: Int -> [Int]
    bar x
        | x == x' = [x]
        | otherwise = x : bar x'
        where x' = foo x

    You here also return the given value first. If the first item in the list should be the number divided by the largest divider, you wan work with:

    bar :: Int -> [Int]
    bar = go . foo
      where go x
              | x == x' = [x]
              | otherwise = x : go x'
              where x' = foo x