2021-02-28

Using System.Random over multiple data types - the Haskell way?

I'm trying to learn Haskell in the most "Haskell way" possible, so I'm trying to avoid things like dos and lets that sort of obscure what's actually going on.

So I have a data type called Org that in is defined as so:

data Org = Org 
    { pos :: Pos2D
    , color :: Color           
    } deriving (Show)

where Color and Pos2D are defined as so:

-- Not actually defined like this, it's Graphics.Gloss.Data.Color
data Color = Color Float Float Float Float
data Pos2D = Pos2D Float Float

Now I've implemented UniformRange for Pos2D and Uniform for Color as so:

instance UniformRange Pos2D
  where
    uniformRM (Pos2D x1 y1, Pos2D x2 y2) g = Pos2D
        <$> uniformRM (x1, x2) g
        <*> uniformRM (y1, y2) g

instance Uniform Color
  where
    uniformM g = G.makeColor
        <$> uniformRM (0.0, 1.0) g
        <*> uniformRM (0.0, 1.0) g
        <*> uniformRM (0.0, 1.0) g
        <*> return 1.0

Given a tuple of Pos2D (representing the corners of the bounds), it will return a random Pos2D distributed uniformly between those. And for Color, it will return a random color with uniform R, G, and B values, but with a fixed alpha = 255 (1.0).

The question is now, how do I make an org?

randomOrg :: RandomGen g => g -> Org
randomOrg = -- ...
  where
    gen = mkStdGen 1337

The issue I'm having is that uniformR and uniformM take a g and return a tuple of (a, g). So I'm not sure what the cleanest, most "Haskelly" way would be to actually chain these calls together to create the Org.

Any thoughts? Thanks,

Edit:

I know that I can do this:

randomOrg :: RandomGen g => g -> Org
randomOrg g = Org pos color
  where
    (pos, g1) = uniformR (Pos2D 0 0, Pos2D 720 480) g
    (color, g2) = uniform g1

But I'm not a fan of that for obvious reasons.



from Recent Questions - Stack Overflow https://ift.tt/2ZYiVAE
https://ift.tt/eA8V8J

No comments:

Post a Comment