2014-09-04 50 views
2

爲了練習Haskell,我實現了Fermat的因式分解方法(參見https://en.wikipedia.org/wiki/Fermat%27s_factorization_method)。然而,當我運行我的程序,哈斯克爾不斷告訴我:haskell:調試<<loop>>異常

$ ./fermat 7 
fermat: <<loop>> 

如此看來,有一個在我的代碼無限循環(CMP http://www.haskell.org/pipermail/haskell-cafe/2013-June/108826.html)。任何人都可以給我一個提示,我做錯了什麼?

另外,我想擴展問題How to debug Haskell code?以獲得有關如何調試此特定異常的提示。

import Data.List 
import System.Environment 
import Debug.Trace 

isQuad :: Integer -> Bool 
isQuad x = a == b 
    where 
     a = ceiling $ s 
     b = floor $ s 
     s = sqrt (fromIntegral x :: Double) 

test :: Integer -> Integer -> Integer -> Bool 
test nr n s = trace(show nr ++ " " ++ show n ++ " " ++ show s) 
    isQuad(
     (+) 
     ((\j -> j * j) s + nr) 
     (-n) 
    ) 

fermat :: Integer -> (Integer, Integer) 
fermat n = (s + x, s - x) 
    where 
     s = ceiling $ sqrt (fromIntegral x :: Double) 
     r = trace 
      (show s ++ " " ++ show n) 
      (\(Just i) -> i) $ 
      find 
      (\nr -> test nr n s) 
      [0..n] 
     x = floor $ sqrt (fromIntegral r :: Double) 

fact :: Integer -> (Integer, Integer) 
fact x 
    | x == 1 = (1, 1) 
    | even x = (2, x `div` 2) 
    | otherwise = fermat x 

f :: String -> String 
f x = x ++ " = " ++ show a ++ " x " ++ show b 
    where 
     (a, b) = fact $ (read x :: Integer) 

main = do 
    args <- getArgs 
    putStrLn $ unlines $ map f args 

回答

5

fermats取決於xx取決於r,並r取決於s

有時懶惰可能會使這種循環依賴性好,但在這種情況下,所有的依賴關係似乎是嚴格的。

這只是從檢查,我沒有任何關於如何調試除了在鏈接後的問題一般問題的任何特別的建議。

我會說<<loop>>意味着運行時系統已經能夠檢測到無限循環,這意味着取決於它自己,例如, let x = x + 1 in x。所以這對於追蹤問題有點線索。

如果你在函數調用中寫了一個無限循環,例如let f x = f x + 1 in f 1,它通常會永遠運行。有時優化器可能會將這些函數調用轉換爲值,但通常不能這樣做。

相關問題