haskell:debugging << loop >>异常

qua*_*ant 2 haskell

为了练习Haskell,我实现了Fermat的分解方法(参见https://en.wikipedia.org/wiki/Fermat%27s_factorization_method).但是,当我运行我的程序时,Haskell一直告诉我:

$ ./fermat 7
fermat: <<loop>>
Run Code Online (Sandbox Code Playgroud)

所以看来,我的代码中存在无限循环(cmp.http ://www.haskell.org/pipermail/haskell-cafe/2013-June/108826.html).任何人都可以给我一个提示,我做错了什么?

另外我想扩展一下如何调试Haskell代码的问题?有关如何调试此特定异常的提示.

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
Run Code Online (Sandbox Code Playgroud)

GS *_*ica 5

在fermat,s取决于x,x取决于r,r取决于s.

有时懒惰可能会使这种循环依赖性正常,但在这种情况下,所有依赖关系似乎都是严格的.

这只是来自检查,我没有任何关于如何调整问题的特别建议,除了在链接的帖子中.

我想说这<<loop>>意味着运行时系统已经能够检测到无限循环,这意味着值依赖于自身,例如let x = x + 1 in x.这是跟踪问题的一点线索.

如果你在函数调用中编写了一个无限循环,例如let f x = f x + 1 in f 1,它通常会永远运行.有时优化器可能会将这些函数调用转换为值,但一般情况下不能这样做.