2

I can't figure out what the bug is in the toy while loop I wrote below. It works for one input, but hangs for other inputs. Here is the code - the while loop takes a vector, a predicate on vector, and transformation function on vector, and returns another vector:

import Data.Vector.Unboxed as U

while :: Vector Int -> (Vector Int -> Bool) -> (Vector Int -> Vector Int) -> Vector Int
while v p f = go 0 v
      where go n x = if (p x) then go (n+1) (f x)
                              else x

test :: Vector Int -> Vector Int
test a = while a (\x -> (x!0) < 2) (\x -> U.map (+1) a)

main = print $ test (U.fromList [0])

This hangs on execution of main. On the other hand, if I change test to:

test a = while a (\x -> (x!0) < 1) (\x -> U.map (+1) a)

I get a termination with result (ghci output below):

λ: main
fromList [1]

I feel I must be missing something. I looked hard at the function, but can't figure out what I am doing wrong. It looks like predicate can't be executed more than twice.

BTW, it works with other types like Int.

   while :: Int -> (Int -> Bool) -> (Int -> Int) -> Int
    while i p f = go 0 i
          where go n x = if (p x) then go (n+1) (f x)
                                  else x

    test :: Int ->  Int
    test a = while a (\x -> x < 2) (\x -> x+1)

    main = print $ test 0

ghci output:

λ: main
2

GHC version: 7.6.1

Vector version: 0.10.0.1

1 Answer 1

6
test a = while a (\x -> (x!0) < 1) (\x -> U.map (+1) a)

should be

test a = while a (\x -> (x!0) < 1) (\x -> U.map (+1) x)

or

test a = while a (\x -> (x!0) < 1) (U.map (+1))

Otherwise the function you are iterating ignores its argument.


Your loop increases a counter, but does not use it. You can remove it:

while v p f = go v
      where go x = if p x then go (f x) else x
1
  • aha, glad to see it was so simple!
    – Sal
    Commented Jun 7, 2013 at 22:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.