[Haskell-beginners] IO ( stuff )

David McBride toad3k at gmail.com
Fri Dec 9 23:05:15 CET 2011


I wish I'd known this when I was first beginning, but it is possible
to do randomness outside of IO, surprisingly easily.  I like to use
the monadRandom library, which provides some monads and monad
transformers for this task.  I too became frustrated when I wrote a
roguelike but could not figure out how to inject randomness into it
when I wanted.  A program you would write might be like this:

data Obstacle = Mon (Int, Int) Monster | Door (Int, Int) | Trap (Int,
Int) deriving (Show, Enum)
data Monster = Orc | Wolf | Dragon deriving (Show, Enum)

main = do
  print =<< evalRandIO randomObstacle

randomObstacle :: RandomGen g => Rand g Obstacle
randomObstacle = do
  x <- getRandomR (0,2::Int)
  case x of
    0 -> Mon <$> randomLocation <*> randomMonster
    1 -> Door <$> randomLocation
    2 -> Trap <$> randomLocation

randomLocation :: RandomGen g => Rand g (Int,Int)
randomLocation = do
  x <- getRandomR (0,10)
  y <- getRandomR (0,10)
  return (x,y)

randomMonster :: RandomGen g => Rand g Monster
randomMonster = do
  x <- getRandomR (0,2::Int)
  return $ case x of
    0 -> Orc
    1 -> Dragon
    2 -> Wolf

This way, even though my randomBlah functions do not have IO in them,
nor do they pass around a stdGen around, but they can be combined
willy nilly as needed, and only computed when you want them to.  I
also could have made Random instances for Obstacle and Monster so that
I did not have to do the cases in the code, making things easier to
understand.

On Fri, Dec 9, 2011 at 3:27 PM, Brent Yorgey <byorgey at seas.upenn.edu> wrote:
>> Does "impurity" from something
>> like a random number generator or file I/O have to move it's way all
>> the way through my code?
>
> No, only through the parts that actually have to do file I/O or
> generate random numbers or whatever.  However, cleanly separating the
> IO code from the non-IO/"pure" code takes some experience.  It does
> seem to be a common experience of people learning Haskell that IO ends
> up "infecting" everything, even stuff that shouldn't have to do any
> IO, but with good design this is not necessary.
>
> In your particular case, your matrix generation function does depend
> on random number generation so it makes sense that its type must
> involve IO. However, if you go on to write other functions which do
> deterministic operations on matrices, their types should *not* involve
> IO, even if you pass randomly generated matrices to them as
> arguments.
>
> -Brent
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners



More information about the Beginners mailing list