How to make a random list using IO in Haskell

haskell, io, monads

Solution

The reason you are getting the error is because `return b : bs` will make the compiler interpret it as `(return b): bs` To fix this, you can change the statement to `return (b:bs)`. That will make the statement return an `IO[Boid]`

Problem

I'm trying to do a flocking simulation in order to better teach myself haskell. I'm running into trouble when trying to generate the initial state for the simulation which requires randomness. I'm trying to generate a list of Boids which all have random initial positions and directions. In the main function I call this using ``` let numBoids = 10 rBoids <- randomBoids numBoids ``` And `rBoids` I indend to store in an IORef which I can then update every frame, which I think is the right way to do things? And here is the code which fails: ``` -- Type for the flocking algorithm data Boid = Boid { boidPosition :: Vector2(GLfloat) , boidDirection :: Vector2(GLfloat) } deriving Show randomBoids :: Int -> IO ([Boid]) randomBoids 0 = do return [] randomBoids n = do b <- randomBoid bs <- (randomBoids (n-1)) return b : bs randomBoid = do pos <- randomVector vel <- randomVector return (Boid pos vel) randomVector = do x <- randomRIO(-1.0, 1.0) y <- randomRIO(-1.0, 1.0) return (Vector2 x y) ``` What actually fails is `return b : bs`. If I change this into `return [b]` it compiles. The error given is: ``` Couldn't match expected type `IO [Boid]' with actual type `[a0]' In the expression: return b : bs In the expression: do { b <- randomBoid; bs <- (randomBoids (n - 1)); return b : bs } In an equation for `randomBoids': randomBoids n = do { b <- randomBoid; bs <- (randomBoids (n - 1)); return b : bs } ``` I'm pretty lost here, and my understanding of the whole imperative-code-in-a-functional language (and monads) is shaky to say the least. Any help would be most appreciated!

Original source