2

while以下に書いたおもちゃのループのバグが何であるかわかりません。1 つの入力では機能しますが、他の入力ではハングします。コードは次のとおりです。while ループは、ベクトル、ベクトルの述語、ベクトルの変換関数を受け取り、別のベクトルを返します。

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

これは の実行時にハングしmainます。一方、次のように変更testした場合:

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

結果で終了します(ghci以下の出力):

λ: main
fromList [1]

私は何かが欠けているに違いないと感じています。関数をよく見ましたが、何が間違っているのかわかりません。述語は 2 回以上実行できないようです。

ところで、それはのような他のタイプで動作します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 出力:

λ: main
2

GHC version: 7.6.1

Vector version: 0.10.0.1

4

1 に答える 1

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
于 2013-06-07T22:27:22.877 に答える