drawing fractals with monads in haskell
dkwise.wordpress.com/2019/02/19/fractals-and-...Posted Mar 20, 2019, 4:32 PM UTC
Posted Mar 20, 2019, 4:32 PM UTC
Haskell beginner here so forgive me if I'm doing something wrong, but your first code example won't run for me. I put this in Fractal.hs file:
-- module Fractal.hs
type Point = (Float,Float)
add :: Point -> Point -> Point
add (x1,y1) (x2,y2) = (x1+x2,y1+y2)
mult :: Float -> Point -> Point
mult r (x,y) = (r*x,r*y)
scaleAround :: Float -> Point -> Point -> Point
scaleAround r p q = ((1-r) `mult` p) `add` (r `mult` q)
triVertices = [(sin(2*k*pi/3), cos(2*k*pi/3)) | k <- [0..2]]
f :: Point -> [Point]
f q = [scaleAround 1 / 2 p q | p <- triVertices]
kpow :: Monad m => Int -> (a -> m a) -> a -> m a
kpow 0 _ = return
kpow n f = f <=< kpow (n-1) f
startPt = (0,0) :: Point
nGens = 10
outputData = kpow nGens f $ startPt
Then I launch gchi from my terminal and get this error:
[Prelude] λ> :l Fractal.hs
[1 of 1] Compiling Main ( Fractal.hs, interpreted )
Fractal.hs:16:8: error:
• Couldn't match type ‘Point -> Point -> Point’
with ‘(Float, Float)’
Expected type: Point
Actual type: Point -> Point -> Point
• Probable cause: ‘(/)’ is applied to too few arguments
In the expression: scaleAround 1 / 2 p q
In the expression: [scaleAround 1 / 2 p q | p <- triVertices]
In an equation for ‘f’:
f q = [scaleAround 1 / 2 p q | p <- triVertices]
|
16 | f q = [scaleAround 1 / 2 p q | p <- triVertices]
| ^^^^^^^^^^^^^^^^^^^^^
Fractal.hs:20:14: error:
• Variable not in scope:
(<=<) :: (a -> m a) -> (a -> m a) -> a -> m a
• Perhaps you meant one of these:
‘=<<’ (imported from Prelude), ‘<=’ (imported from Prelude)
They are probably using a different Prelude like Protolude that exports (<=<) you can fix the second error by adding import Control.Monad ((<=<)) at the top of the file.
Edit: For the first error, I think the definition for f should be:
f q = [scaleAround (1 / 2) p q | p <- triVertices]
Awesome, both those worked. Thank you very much for the help. May I ask another question?
When I load the module and run outputData I get a seemingly endless list of tuples. Is there a way to plot this data? Does haskell have a plotting library?
To plot something like this, I'd use rasterific (http://hackage.haskell.org/package/Rasterific) personally.
Reminded me on this animation, while taking a different approach.
Very well written. An enjoyment to read. I love these little elegant applications of Haskell. I made a thing similar in spirit to this for drawing "spirographs" as a means of teaching my girlfriend programming https://github.com/fredefox/spirograph