Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Can you set the field of a record using an IO function (inside a do statement)?

In my main function for my haskell game, I start by loading each sprite. I decided to make a data type called SpriteCollection which holds all the sprites (typed Picture) so I can access them later by their name.

loadBMP is a Gloss function typed String -> IO Picture. This code works:

main = do
  -- Load sprites
  playerBmp <- loadBMP "assets/mario.bmp"
  goombaBmp <- loadBMP "assets/goomba.bmp"
  brickBmp <- loadBMP "assets/brick.bmp"
  let sprites = SpriteCollection { 
      marioSprite = playerBmp,
      goombaSprite = goombaBmp
      brickSprite = brickBmp
    }
  playIO (... sprites ...)

So as you can see, as I load more sprites, it feels like I am writing double the code that I should need. Is there a way to get rid of the intermediate variables? For example:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

main = do
  -- Load sprites
  let sprites = SpriteCollection { 
      marioSprite <- loadBMP "assets/mario.bmp",
      goombaSprite <- loadBMP "assets/goomba.bmp",
      brickSprite <- loadBMP "assets/brick.bmp"
    }
  playIO (... sprites ...)

but that does not work.

>Solution :

Applicative is the tool for combining multiple values that are in the same sort of context.

main = do
  sprites <- SpriteCollection <$> 
    loadBMP "mario" <*> 
    loadBMP "goomba" <*> 
    loadBMP "brick"
  ...

In general,

do
  x <- mx
  y <- my
  return (f x y)

can be written as

f <$> mx <*> my

but only if the final call to f is the only thing that references x and y. This approach scales to arbitrarily many arguments. For small numbers of arguments, you can try something from the liftA family of functions, such as liftA2 f mx my.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading