2014-09-04 54 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,它通常会永远运行。有时优化器可能会将这些函数调用转换为值,但通常不能这样做。

相关问题