[英]Haskell infinite recursion in list comprehension
我試圖定義一個函數,它接受一個點 (x,y) 作為輸入,並返回一個對應於遞歸調用的無限列表
P = (u^2 − v^2 + x, 2uv + y)
u 和 v 的初始值都是 0。
第一個電話是
P = (0^2 - 0^2 + 1, 2(0)(0) + 2) = (1,2)
那么結果元組 (1,2) 將是 u 和 v 的下一個值,因此它將是
P = (1^2 - 2^2 + 1, 2(1)(2) + 2) = (-2,6)
等等。
我想弄清楚如何在 Haskell 中對此進行編碼。 這是我到目前為止:
o :: Num a =>(a,a) -> [(a,a)]
o (x,y) = [(a,b)| (a,b)<- [p(x,y)(x,y)]]
where p(x,y)(u,v) = ((u^2)-(v^2)+x,(2*u*v)+y)
我真的不知道如何使這項工作。 任何幫助,將不勝感激!
讓我們首先忽略您的確切問題,並專注於使循環正常工作。 本質上,您想要的是具有一些初始值iv
(即(0, 0)
for (u, v)
),並返回列表
f iv : f (f iv) : f (f (f iv)) : f (f (f (f iv))) : ...
對於某些函數f
(從您的p
和(x, y)
構建)。 此外,您希望結果重用先前計算的列表元素。 如果我自己編寫一個執行此操作的函數,它可能看起來像這樣(但可能有一些不同的名稱):
looper :: (a -> a) -> a -> [a]
looper f iv = one_result : more_results
where
one_result = f iv
more_results = looper f one_result
但是,當然,我會首先查看是否存在具有該類型的函數。 它確實:它被稱為Data.List.iterate
。 它唯一做錯的是列表的第一個元素將是iv
,但這可以通過使用tail
輕松修復(這里很好:只要您的迭代函數終止, iterate
將始終生成一個無限列表)。
現在讓我們回到你的案例。 我們確定它通常看起來像這樣:
o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate f iv)
where
f (u, v) = undefined
iv = undefined
正如您所指出的, (u, v)
的初始值是(0, 0)
,這就是我們對iv
的定義。 f
現在必須使用o
的參數中的(x, y)
和該迭代的(u, v)
調用p
:
o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate f iv)
where
f (u, v) = p (x, y) (u, v)
iv = (0, 0)
p = undefined
就這么簡單: o
定義中的(x, y)
實際上在where
子句中的范圍內。 你甚至可以決定合並f
和p
,最后得到
o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate p iv)
where
iv = (0, 0)
p (u, v) = (u^2 - v^2 + x, 2 * u * v + y)
另外,我可以建議您將Data.Complex
用於您的應用程序嗎? 這使得在限制a
有點更嚴格的(你需要RealFloat a
,因為Num.signum
),但在我看來,它使你的代碼更容易閱讀:
import Data.Complex
import Data.List (iterate)
{- ... -}
o :: Num (Complex a) => Complex a -> [Complex a]
o c = tail (iterate p iv)
where
iv = 0 -- or "0 :+ 0", if you want to be explicit
p z = z^2 + c
你要:
[(u, v)]
,這個列表的頭部等於(0, 0)
\\(u, v) -> (u^2 - v^2 + x, 2 * u * v + y)
map
此列表,將此函數的結果附加到列表中。我們可以像描述的那樣編寫這個函數:
func :: (Num t) => (t, t) -> [(t, t)]
func (x, y) = (0, 0) : map functionP (func (x, y))
where functionP (u, v) = (u^2 - v^2 + x, 2 * u * v + y)
GHCi > take 5 $ func (1, 2)
> [(0,0),(1,2),(-2,6),(-31,-22),(478,1366)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.