Lazy ReplicateM?

After some help last week on this forum, I generate 2 lists, put them together and shuffle them.

-- adult German males and females with random heights

fs :: State StdGen [Float]
fs = replicateM depth $ state $ normal' (166,6)

ms :: State StdGen [Float]
ms = replicateM depth $ state $ normal' (179,6)

-- heights

hs :: State StdGen [Float]
hs = join $ (\ ms fs -> shuffle $ ms ++ fs) <$> ms <*> fs

Is there a way to avoid replicating with a specific depth for each list, but take put them together and then do a take with a specific length, i.e.:

take depth hs

without referring to depth in ms & fs.

Have you tried something like

replicateForever :: m a -> m [a]
replicateForever act = do
  v <- act
  rest <- replicateForever act
  pure $ v : rest

(you may need to use lazy State in your example).

1 Like

Not really, because you need a way to specify how many elements to take from fs and how many from ms! If you write take 10 hs there’s no way to specify whether that means 5 from fs and 5 from ms, 4 from fs and 6 from ms, 1 from fs and 9 from ms, … the problem is underconstrained!

3 Likes

V true!! I didn’t think about this - back to the drawing board : )