fredefox•

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

10
keepitsalty•

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)
3
lgastako•

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]
5
keepitsalty•

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?

4
merlin_thp•

To plot something like this, I'd use rasterific (http://hackage.haskell.org/package/Rasterific) personally.

5
BanX•

Reminded me on this animation, while taking a different approach.

2