我想在haskell中计算给定点的复数多项式的值。
多项式作为((Int,Int),Int)
元素的列表给出,其中(Int,Int)
对代表商的实数和虚数单位,剩余的Int
代表度数。因此,复数点x
中的多项式的值被计算为a_i*(x^t)
的总和,其中a_i
是i
商和t
度。
这是我的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
我不知道为什么会发生这种情况或如何调试它。
答案 0 :(得分: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)
这对我来说是正确的。
答案 1 :(得分:3)
问题在于,您%^
的实施仅针对n >= 1
定义,但您尝试将其与n = 0
一起使用,n = 1
永远不会达到基本情况({{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
执行。这表明非终止递归存在问题。