Bug in while loop

Refresh

November 2018

Views

129 time

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

Sal

1 answers

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

должно быть

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

или же

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

В противном случае функция вы перебор игнорирует свой аргумент.


Ваш цикл увеличивает счетчик, но не использует его. Вы можете удалить его:

while v p f = go v
      where go x = if p x then go (f x) else x