Haskell Random Generator ... how to make it easier to use?

I have problems with the Haskell Random generator. At university, I have to deal with Java all the way, so now I'm spoiled for it. I am developing a game in Haskell, and now I come across something like a โ€œchance to do something,โ€ and this chance should be like Int -> Bool . In Java, I would do

 new Random().nextInt(100) 

and there the problem is solved! In Haskell, I have to select something in the IO monad or something with a seed. None of them do what I want. I really do not want to use IO monad in my pure model, and the seed is inconvenient to use, because I need to remember my new seed every time ...

Is there something simple like Java Random?

+6
source share
4 answers

Believe it or not, you have to use different approaches in Haskell than in Java. There are several packages that may help you, but you will need to take a different look at them in order to use them successfully. Here are a few pointers:

A search for the word "random" on the Hackage Package List will include many more specific packages for more specific needs.

+12
source

Sorry, but you have to live with it. How can there be a function in a pure functional language that gives you different meanings for each call? The answer is this: it cannot - only in IO-Monad or something similar, like a state monad, where you can pass your seed around (and not have the same input every time), whether such things can exist.

You can also look at this question, โ€œ How can there be a time function in functional programming? โ€ As in the same direction as yours.

+7
source

It is not clear that something that does not require input and output should be processed as if it were. Say you defined it as follows:

 random100 = unsafePerformIO $ randomRIO (1, 100) -- This will not work! 

It really will give you a random number - in a way . What you really need is a way of encoding what you want to get a new pseudo-random number every time. This means that information must go from one generation of random numbers to another. Most languages โ€‹โ€‹simply ignore this "trifle", but Haskell makes you pay attention. You can thank Haskell when you are in place to correctly reproduce your pseudo-random result in a multi-threaded context.

There are several ways to make these compounds, most of which are already mentioned. If you are reluctant to use the monad: note that, as a rule, it would be nice to have the code in monadic form (but not using IO !). In the future, it may well come to you in a situation where you want more monad features, such as a reader for configuration, then all the work on earth will already be completed.

+2
source

I think, โ€œyou have to live with it,โ€ is neither useful nor right. It depends on the abstractions you use. If your application, of course, is connected with a monad, then it makes sense to use a random number generator with a monad, which is as convenient as a Java random number generator.

In the case of a game using modern abstractions, your application is naturally related to functional reactive programming (FRP), where random number generation is not a problem at all and does not require you to skip generators explicitly. An example of using the netwire library:

 movingPoint :: MonadIO m => (Double, Double) -> Wire ma (Double, Double) movingPoint x0 = proc _ -> do -- Randomly fades in and out of existence. visible <- wackelkontakt -< () require -< (visible, ()) -- 'rnd' is a random value between -1 and 1. rnd <- noise1 -< () -- dx is the velocity. let dx = (sin &&& cos) (rnd * pi) -- Integration of dx over time gives us the point position. -- x0 is the starting point. integral x0 -< dx 

Is there any way to express this easier and shorter? Probably not. FRP also proves that Zhen is not wrong. It can only handle user input.

+2
source

Source: https://habr.com/ru/post/896762/


All Articles