I am with trouble related to Haskell Random generator. At university, i have to deal with Java all my way around, so now I'm, corrupted with it.
I am developing a game in Haskell, and now I face something like 'chance to do something', and that chance needs to be like Int -> Bool
. In Java, I would have done
new Random().nextInt(100)
and there, problem solved! In Haskell I have to choose something in a monad IO or something with a seed. None of these does what I want. I don't really want to use IO monad in my pure model, and the seed is awkward to use because I need to remember my new seed every time...
Is there something simple like Java's Random?
I think, "you will have to live with that", is neither useful nor correct. It really depends on the abstractions you are using. If your application is naturally bound to a monad, then it makes sense to use a monadic random number generator, which is just as convenient as Java's random number generator.
In the case of a game using modern abstractions your application is naturally bound to functional reactive programming (FRP), where generating random numbers is no problem at all and doesn't require you to pass around generators explicitly. Example using the netwire library:
Is there any way to express this easier and more concisely? I guess not. FRP also proves Zhen's comment wrong. It can handle user input purely.
Believe it or not, you'll have to use different approaches in Haskell than you did in Java. There are a couple packages that can help you, but you will have to get a different attitude in your head to use them successfully. Here are some pointers:
Searching for the word "random" on Hackage's package list will turn up many, many more specific packages for more specific needs.
It is somewhat unintuitive that something that neither does input nor output needs to be handled as if it had. Let's say you defined it as follows:
That would indeed give you a random number - in a way. What you truly need is a way to encode that you want a new pseudo-random number every time. This means information needs to go from one random number generation to the next. Most languages just ignore this "minor detail", but Haskell forces you to pay attention. You might thank Haskell when you find yourself in the spot to properly reproduce your pseudo-random result in a multi-threaded context.
There's a number of ways you can make these connections, most of which have been mentioned already. If you are reluctant to use a monad: Note that it might generally be a good thing to have your code in a monadic form (but not using
IO
!). Down the road, you might well come into situations where you want more monad features, such as a reader for configuration - then all ground work would be done already.Sorry, but you will have to live with that. How can there be a function in a pure functional language that gives you different values on each call? Answer is: it cannot - only in the IO-Monad or something similiar like the state-monad where you can pass your seed around (and don't have the same input every time) can such a things exist.
You may alsow have a look as this question "How can a time function exist in functional programming?" as it's in the same direction as yours.