bez uciekania się do wszelkiego rodzaju niebezpieczne nie jest możliwe, aby taka funkcja miała raczej typ Int
niż typ IO Int
lub coś podobnego. Funkcje (lub, w tym przypadku, stałe) typu Int
są czyste, co oznacza, że za każdym razem, gdy "wywołasz" funkcję (odczytaj wartość stałej), masz gwarancję otrzymania tej samej wartości "zwróconej".
Jeśli chcesz mieć inną, losowo wybraną wartość zwracaną przy każdym wywołaniu, będziesz musiał użyć zmiennej -monad IO
.
W niektórych przypadkach może być potrzebna pojedyncza losowo wytworzona wartość dla całego programu, tj. Taki, który z perspektywy programu zachowuje się tak, jakby był czystą wartością. Za każdym razem, gdy wyszukujesz wartość w tym samym przebiegu programu, odzyskujesz tę samą wartość. Ponieważ cały program jest w istocie wynikiem działania w postaci IO
, możesz raz wygenerować tę wartość i przekazać ją dookoła, ale może to być trochę niezręczne. Można argumentować, że w tej sytuacji, to jest wciąż bezpieczny powiązać wartości ze stałą najwyższego poziomu typu Int
i używać unsafePerformIO
skonstruować że Constant:
import System.IO.Unsafe -- be careful!
import System.Random
-- a randomly chosen, program-scoped constant from the range [0 .. 9]
c :: Int
c = unsafePerformIO (getStdRandom (randomR (0, 9)))
http: // stackoverflow .com/a/2738824/570689 - dobra odpowiedź na podobne pytanie –
Brzmi jak najlepsze, na co można liczyć, to "randomInt lo hi = lo" lub coś podobnego. Bez jakiegoś nasienia lub IO funkcja musi zawsze zwracać tę samą wartość. A dolna granica jest tak samo losowa, jak każde inne "Int". :) – augustss
"Każdy, kto rozważa arytmetyczne metody wytwarzania losowych cyfr, jest oczywiście w stanie grzechu." Przypisany Johnowi Vonowi Neumannowi _ in_ Knuth, D. _ The Art of Computer Programming_, tom 2, s. 1 (1981). – rickythesk8r