2

TI Basicで作成したこの複雑な反復プログラムを使用して、複素数に対して基本的な反復を実行し、結果の大きさを示します。

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

私がやりたいのは、これのHaskellバージョンを作成して、課題で先生を驚かせることです。私はまだ学んでいて、ここまで進んでいます:

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

3 に答える 3

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)

Complex はデフォルトで文字列との間で変換できるため、 を使用readLnしてコンソールから読み取ることができます (形式は ですRe :+ Im)。

編集:楽しみのために、プログラム全体をこれに圧縮するモナド構文と型シグネチャを脱糖することができます:

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: プロットとマンデルブロの集合に関連するいくつかのリンク。

于 2009-09-12T11:44:38.580 に答える
3

繰り返し適用した結果の無限のリストをいつでも生成し、nを使用してそれらの最初のものを取得できますtake。また、このiterate関数は、繰り返し適用した結果の無限リストを生成するのに役立ちます。

于 2009-09-12T07:16:28.163 に答える
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)) 

(ただし、(take n (repeat c)) のことは不必要に思えますが、もっと良い方法があるはずです)

于 2009-09-12T08:02:52.793 に答える