我在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
进行比较看看它是否已经完成。
我该怎么做?
答案 0 :(得分:4)
Newacct的回答显示了方式:
fractal c n = take n $ iterate (\z -> z^2 + c) c
Iterate
生成重复应用程序的无限列表。
例如:
iterate (2*) 1 == [1, 2, 4, 8, 16, 32, ...]
关于IO,你必须做一些monadic计算。
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
)。
编辑:只是为了好玩,人们可以去掉monadic语法和类型签名,这会将整个程序压缩到这个:
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集相关的链接。
答案 1 :(得分:3)
您可以随时生成重复应用程序的无限结果列表,并使用n
获取它们的第一个take
。 iterate
函数对于生成重复应用程序的无限结果列表非常有用。
答案 2 :(得分: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新手。
编辑:只是为了踢,一个折叠单行:
fractalFold c n = foldr (\c z -> z^2 + c) c (take n (repeat c))
(虽然(拿n(重复c))事情似乎没什么必要,但必须有更好的方法)