[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