2009-09-12 80 views
2

我有這個複雜的迭代程序我在TI基本寫信給在複數執行基本的迭代,然後給結果的大小:複雜的迭代

INPUT 「SEED?」, C 
INPUT 「ITERATIONS?」, N 
C→Z 
For (I,1,N) 
Z^2 + C → Z 
DISP Z 
DISP 「MAGNITUDE」, sqrt ((real(Z)^2 + imag(Z)^2)) 
PAUSE 
END 

我想這樣做是做一個哈斯克爾版本,讓我的老師在任務中。我仍然只是在學習,走到這一步:

fractal ::(RealFloat a) => 
      (Complex a) -> (Integer a) -> [Complex a] 
fractal c n | n == a = z : fractal (z^2 + c) 
    | otherwise = error "Finished" 

我不知道該怎麼辦是如何使它只迭代n次,所以我想有指望了a,然後把它比作n看看它是否完成。

我該怎麼辦?

回答

4

Newacct的回答顯示方式:

fractal c n = take n $ iterate (\z -> z^2 + c) c 

Iterate產生重複應用的無限名單。 例如:

iterate (2*) 1 == [1, 2, 4, 8, 16, 32, ...] 

關於IO,你就必須做一些一元計算。

import Data.Complex 
import Control.Monad 

fractal c n = take n $ iterate (\z -> z^2 + c) c 

main :: IO() 
main = do 
    -- Print and read (you could even omit the type signatures here) 
    putStr "Seed: " 
    c <- readLn :: IO (Complex Double) 

    putStr "Number of iterations: " 
    n <- readLn :: IO Int 

    -- Working with each element the result list 
    forM_ (fractal c n) $ \current -> do 
     putStrLn $ show current 
     putStrLn $ "Magnitude: " ++ (show $ magnitude current) 

由於複雜的是默認的,並串轉換,你可以使用readLn從控制檯讀取它們(格式爲Re :+ Im)。

編輯:只是爲了好玩,人們可以desugar的單子語法和類型簽名這將整個PROGRAMM壓縮到這一點:

main = 
    (putStr "Seed: ") >> readLn >>= \c -> 
    (putStr "Number of iterations: ") >> readLn >>= \n -> 
    forM_ (take n $ iterate (\z -> z^2 + c) c) $ \current -> 
    putStrLn $ show current ++ "\nMagnitude: " ++ (show $ magnitude current) 

編輯#2:有關策劃和Mandelbrot的集合的幾個環節。

+0

謝謝,如果結果出現在mandlebrot集(當幅度<2)時,有沒有什麼辦法可以用一些瘋狂的顏色來繪製這個圖? – 2009-09-12 13:11:46

+0

編輯我的文章 - 一些非常有趣的鏈接;-) – Dario 2009-09-12 13:37:33

+0

我正在編譯所有這些和分形繪圖儀,併發送我的老師一個可執行文件。 – 2009-09-12 14:43:31

3

那麼你總是可以生成一個無限重複應用程序的結果列表,並採取take他們的第一個n。而iterate函數對於生成重複應用程序的無限列表結果非常有用。

2

如果您想值的列表:

fractalList c n = fractalListHelper c c n 
        where 
        fractalListHelper z c 0 = [] 
        fractalListHelper z c n = z : fractalListHelper (z^2 + c) c (n-1) 

如果你只關心最後的結果:

fractal c n = fractalHelper c c n 
        where 
        fractalHelper z c 0 = z 
        fractalHelper z c n = fractalHelper (z^2 + c) c (n-1) 

基本上,在這兩種情況下,你需要一個輔助函數來計數和積累。現在我確信有一個更好/更少的方法來做到這一點,但我幾乎是一個Haskell新手自己。

編輯:只是踢,一個foldr相似的一行:

fractalFold c n = foldr (\c z -> z^2 + c) c (take n (repeat c)) 

(雖然,在(取n(重複c))的東西似乎有點多餘,必須有一個更好的方法)

+0

我認爲這是更好地使用'foldl'',而不是'foldr'像'fractalFold CN =與foldl」(\ ZC - > Z 2 2 + c)c(取n(重複c))'。因爲'foldr'是懶惰的。這意味着它會根據給定列表的長度創建thunk,但返回類型「fractalFold」不需要懶惰。 – nonowarn 2010-01-29 03:46:53