How can I get a random value in a range determined by a signal?

两盒软妹~` 提交于 2019-12-11 01:38:02

问题


First some code:

import Random
import Window

writeRandom x = lift asText (Random.range 0 x <| every second)

upperLimit = 300
-- upperLimit = Window.width -- How can i use this instead?

main = writeRandom upperLimit

Ultimately I'm trying to get random points on the screen, but I can't figure out how to pass Window.height and Window.width to Random.range. I don't think I can 'lift' Random.range, since it already returns a signal. If I try I get a type error:

Type Error: 'main' must have type Element or (Signal Element).
Instead 'main' has type:

   Signal (Signal Element)

And I'm not sure that the opposite of lift (lower?) exists, or even makes sense.

Thanks


回答1:


You are correct in supposing that an opposite of lower doesn't make sense.
In this particular case, the builtin Random library is builtin because it's a wrapper around a native JavaScript call. This is the reason for the Signal return type, to keep the code pure. And even then, it's not completely well-behaved.

To get the kind of random range you want, you'll need a different random number generator. There is a community library that was published only a few days ago, that'll probably answer your needs. You can check it out of GitHub yourself, or use the elm-get tool.

Your code would become something like (untested!):

import Window
import Generator
import Generator.Standard as GStd

randomSeed = 12346789

writeRandom : Signal Int -> Signal Element
writeRandom x = 
  let update high (_, gen) = Generator.int32Range (0,high) gen
      start = (0, GStd.generator randomSeed)
      input = sampleOn (every second) x
      result = fst <~ foldp update start input
  in  lift asText result

upperLimit = Window.width

main = writeRandom upperLimit

In writeRandom, you use foldp to keep the latest random-number generator. In update you use this to get a new random number and a new generator for the next time. The input of x is updated every second by using sampleOn (every second). The fst <~ part is to remove the random number generator, since you only want the random number.



来源:https://stackoverflow.com/questions/21360434/how-can-i-get-a-random-value-in-a-range-determined-by-a-signal

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!