0

我想在haskell中计算给定点的复数多项式的值。

多项式以((Int,Int),Int)元素列表的形式给出,其中一对(Int,Int)代表商的实部和虚部,其余Int代表度。因此,复点中多项式的值x被计算为a_i*(x^t)其中th 商和次数a_i之和。it

这是我的haskell代码:

type Komp = (Int, Int)
(+%) :: Komp -> Komp -> Komp
(r1, i1) +% (r2, i2)    = (r1+r2, i1+i2)

(*%) :: Komp -> Komp -> Komp
(r1, i1) *% (r2, i2)    = (r1*r2 - i1*i2, r1*i2 + i1*r2)

(^%) :: Komp -> Int -> Komp
k ^% 1      = k
k ^% n      = (k ^% (n-1)) *% k

vredKompPol :: [(Komp,Int)] -> Komp -> Komp
vredKompPol ((k,s):poli) t  = k*%(t^%s) +% (vredKompPol poli t)

+%,只不过是操作,*%并且定义在由类型表示的复数上。^%+*^Komp

它可以很好地加载拥抱,但执行:

Main> vredKompPol [((1,1),2),((1,1),0)] (0,0)

抛出错误:

ERROR - Control Stack Overflow

我不知道它为什么会发生或如何调试它。

4

2 回答 2

4

我发现至少有两个错误。导致您的问题的一个原因是您的基本情况(^%)太高了,所以

> (1,1) ^% 0
*** Exception: stack overflow

通过将基本情况更改为来修复它

k ^% 0 = (1, 0)

第二个是你没有基本情况vredKompPol,你可以通过添加一个像这样的子句来解决这个问题

vredKompPol [] _ = (0, 0)

通过这两个更改,我得到:

*Main> vredKompPol [((1,1),2),((1,1),0)] (0,0)
(1,1)

这对我来说是正确的。

于 2015-01-11T19:45:33.197 回答
3

问题是您的实现%^仅定义为n >= 1,但您试图将它与 一起使用n = 0,它永远不会达到基本情况(n = 1)。

现在,拥抱已经停止开发,所以我建议改用 ghci。在 ghci 中,您可以像这样调试类似的问题:

[jakob:~]$ ghci foo.hs
GHCi, version 7.8.4: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main             ( foo.hs, interpreted )
Ok, modules loaded: Main.

设置一个标志以在 Ctrl-c 上启用中断:

*Main> :set -fbreak-on-error

跟踪有问题的函数:

*Main> :trace vredKompPol [((1,1),2),((1,1),0)] (0,0)

片刻之后,按 Ctrl-c 停止执行。

^CStopped at <exception thrown>
_exception :: e = _

:history显示执行历史。

[<exception thrown>] *Main> :history
-1  : *% (foo.hs:6:1-56)
-2  : ^% (foo.hs:10:15-31)
-3  : ^% (foo.hs:10:22-24)
-4  : ^% (foo.hs:(9,1)-(10,31))
-5  : ^% (foo.hs:10:16-25)
-6  : *% (foo.hs:6:1-56)
-7  : ^% (foo.hs:10:15-31)
-8  : ^% (foo.hs:10:22-24)
-9  : ^% (foo.hs:(9,1)-(10,31))
-10 : ^% (foo.hs:10:16-25)
-11 : *% (foo.hs:6:1-56)
-12 : ^% (foo.hs:10:15-31)
-13 : ^% (foo.hs:10:22-24)
-14 : ^% (foo.hs:(9,1)-(10,31))
-15 : ^% (foo.hs:10:16-25)
-16 : *% (foo.hs:6:1-56)
-17 : ^% (foo.hs:10:15-31)
-18 : ^% (foo.hs:10:22-24)
-19 : ^% (foo.hs:(9,1)-(10,31))
-20 : ^% (foo.hs:10:16-25)
...

用于:back向上移动执行历史记录,以便使用以下命令检查参数:show bindings

[<exception thrown>] *Main> :back
Logged breakpoint at foo.hs:6:1-56
_result :: Komp
[-1: foo.hs:6:1-56] *Main> :show bindings
_exception :: e = _
_result :: Komp = _

这里没有什么有趣的(可能是因为它是按下 Ctrl-c 时正在执行的函数)。上一步再试一次:

[-1: foo.hs:6:1-56] *Main> :back
Logged breakpoint at foo.hs:10:15-31
_result :: Komp
k :: Komp
n :: Int
[-2: foo.hs:10:15-31] *Main> :show bindings
_exception :: e = _
n :: Int = -12390
k :: Komp = (0,0)
_result :: Komp = _
[-2: foo.hs:10:15-31] *Main> 

因此,它在第 10 行执行,带有n = -12390. 这表明非终止递归存在问题。

于 2015-01-11T19:49:43.167 回答