问题
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