讓我們首先忽略你的確切問題,並着重於讓循環工作。你想要什麼,本質上,是有東西,需要一些初始值iv
(即(0, 0)
爲(u, v)
),並返回列表
f iv : f (f iv) : f (f (f iv)) : f (f (f (f iv))) : ...
一些功能f
(從p
和(x, y)
構造)。而且,您希望結果重用列表中先前計算的元素。如果我會寫一個函數自己,這樣做,它可能looke這樣的(但也許有些不同的名稱):
looper :: (a -> a) -> a -> [a]
looper f iv = one_result : more_results
where
one_result = f iv
more_results = looper f one_result
但是,當然,我會先look如果與類型的函數存在。它確實:它被稱爲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
現在有打電話給p
與(x, y)
從o
的說法和(u, v)
該次迭代:
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
它就是這麼簡單:(x, y)
從o
的定義實際上是在範圍上的where
-clause 。你甚至可以決定合併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
['迭代P(0,0)'](http://hackage.haskell.org/package/base-4.9.0.0 /docs/Prelude.html#v:iterate)? – Bergi
請不要刪除您的示例代碼。每個人都從某個地方出發。有沒有必要爲此感到羞恥:) – 2016-10-01 18:35:54
@Rhymoid,你是在暗示我的小學標誌,BASIC和Turbo Pascal代碼可能有什麼值得期待的地方嗎?我自己只寫過完美的代碼,我期望其他人也一樣。編程是嚴肅的事務,並且沒有任何錯誤的餘地! – dfeuer