To get used to Haskell, I wrote a little program using the Diagrams package which generates 100 random dots (larger dots are more likely to be in the center).Sample output:My questions:Is the program well structured with respect to the IO monad and the random values (see types for randomDot and randomDots)? Should I organize the code differently to keep more code out of the IO monad?Other nitpicks?module Main (main) whereimport Data.Colour.SRGBimport Data.Random.Sourceimport Diagrams.Backend.SVG.CmdLineimport Diagrams.Preludeimport qualified Data.Random as Rdata Dot = Dot { _dotCenter :: R2               , _radius :: Double               , _color :: Colour Double                } deriving Showcolors :: [Colour Double]colors = map sRGB24read [          bf3131,          f5b456,          a89178,          615b5b,          add274,          b9a1b9,          f0a2bc,          eb565c,          d15f69,          48bdbe,          f1ede2]-- |Generate a single dot with random location, radius, and color.randomDot :: Double -> R.RVar DotrandomDot x = do  let mu_rad = 15 * exp (-4 * x)      sigmaSq_rad = 0.3 * mu_rad      sigmaSq_loc = 8 * exp (2.5*x)  locX <- R.sample (R.normal 0 sigmaSq_loc)  locY <- R.sample (R.normal 0 sigmaSq_loc)  radius <- abs <$> R.sample (R.normal mu_rad sigmaSq_rad)  color <- R.sample (R.randomElement colors)  return $ Dot (r2 (locX, locY)) radius color-- |Recursively generate random dots and check that they do not-- overlap.randomDots :: [Dot] -> [Double] -> IO [Dot]randomDots dots [] = return dotsrandomDots dots (x:xs) = do  dot <- R.sample $ randomDot x  if any (tooClose dot) dots  then randomDots dots (x:xs)  else randomDots (dot:dots) xstooClose :: Dot -> Dot -> BooltooClose x y = dist < 1.1 * radiusSum    where      dist = magnitude $ _dotCenter x ^-^ _dotCenter y      radiusSum = _radius x + _radius ydotsToDiagram :: [Dot] -> Diagram B R2dotsToDiagram = mconcat . map fromDotfromDot :: Dot -> Diagram B R2fromDot c = circle (_radius c) # fc (_color c)                               # lw none                               # translate (_dotCenter c)main :: IO ()main = mainWith . dotsToDiagram =<< randomDots [] [0.01, 0.02..1.0]
Random numbers, IO monad, and pure code
haskell;random;graphics;monads