How to check multiline case?

Hi everyone! I’m new to Haskell and I started from Haskell MOOC. Now I’m in lecture 3 exercises and wondering how to solve that one:

-- Ex 7: implement a functional while loop. While should be a function

-- that takes a checking function, an updating function, and an

-- initial value. While should repeatedly apply the updating function

-- to the initial value as long as the value passes the checking

-- function. Finally, the value that doesn't pass the check is

-- returned.

--

-- Examples:

--

--   while odd (+1) 1    ==>   2

--   while (<=4) (+1) 0  ==>   5

--

--   let check [] = True

--       check ('A':xs) = False

--       check _ = True

--   in while check tail "xyzAvvt"

--     ==> Avvt

I wrote that one and it’s working for 1st and 2nd cases:

while :: (a->Bool) -> (a->a) -> a -> a

while check update value = if check (update value)

    then while check update (update value)

    else update value

I’m wondering how to do it for 3rd like cases. I need some advices please

Your code seems to work fine for the third case. Can you explain what you think the problem is? What did you do that went wrong and what did you expect to happen?

Maybe I’m checking wrong. I wrote the test case in cabal repl and it didn’t work… Also when I check it with “cabal exec runhaskell Set3aTest.hs” it giving me that message:

===== EXERCISE 7
*** Failed! Timeout of 5000000 microseconds exceeded. (after 11 tests):
while (/=0) (+1) 0

----- Fail

This is an infinite loop, is it not? It’ll never be not not equal zero, so it’ll never stop as you keep adding.

The while (/=0) (+1) 0 is indeed problematic with your current implementation.


Edit: first think about what you expect from this. What do you think it should do?

To check perhaps try the equivalent in another language like python:

x = 0
while (x != 0):
  x = x + 1
print(x)

One way to debug these kinds of problems is to think through what happens when you pass these values to the right hand side function. In this case you have check = (/= 0), update = (+ 1), and value = 0, so the right hand side becomes:

if ((/= 0) ((+ 1) 0) then while (/= 0) (+ 1) ((+ 1) 0) else (+ 1) 0

This can be written more nicely by turning the operator sections into fully applied operators:

if (0 + 1 /= 0) then while (/= 0) (+ 1) (0 + 1) else 0 + 1

Can you reason through what happens in this case and why it is not what you expect?

I can’t explain but I fixed the code :sweat_smile:
Instead of checking “update value” I checked value
Thank you so much.