Standardbibliothek
Antra::Random
import Antra::RandomPseudozufallszahlen fuer Antra auf Basis eines seed-threadenden RNG-Modells.
Der Grundtyp in diesem Paket ist ein RNG-Wert der Form:
|seed| -> [wert, neuer_seed]Dieser RNG-Typ kann mit step(...), sample(...), map_gen(...) und
bind(...) kombiniert werden.
Wenn du daraus einen echten gen fn-Generator fuer take(...),
for ... in ... oder next(...) machen willst, benutze stream(rng, seed).
Deterministisch (gleicher Seed → gleiche Ausgabe):
my s = Random.seed(42)
my r = Random.step(Random.int(1, 6), s)
println(r[0])Als echter Sprach-Generator:
my g = Random.stream(Random.int(1, 6), Random.seed(42))
println(take(g, 5))Nicht deterministisch (zeitbasierter Seed):
my roll = Random.sample(Random.int(1, 6))
println(roll)Überblick#
Fuer deterministische Pseudozufallswerte mit explizitem Seed.
Der Grundtyp in Antra::Random ist zunaechst kein Sprach-Generator, sondern
ein seed-threadender RNG-Wert dieser Form:
|seed| -> [wert, neuer_seed]Darum liefern Funktionen wie int(...), float(...) oder bool() nicht
direkt etwas, ueber das du mit for ... in ... iterieren kannst. Stattdessen
arbeitest du zuerst mit step(...) oder sample(...):
import Antra::Random as Random
my seed = Random.seed(42)
my [roll, next_seed] = Random.step(Random.int(1, 6), seed)
println(roll)Fuer enge Hotpaths gibt es auch einen direkten Fast-Path ohne vorherigen Generator-Closure-Bau:
import Antra::Random as Random
my [roll, next_seed] = Random.int_step(1, 6, Random.seed(42))
println(roll)Wenn du daraus einen echten Sprach-Generator machen willst, gibt es den Adapter
stream(...):
import Antra::Random as Random
my rolls = Random.stream(Random.int(1, 6), Random.seed(42))
println(take(rolls, 5))Die praktische Trennung ist also:
int(...),float(...),bool(),uniform(...),weighted(...): bauen RNG-Wertestep(...)undsample(...): fuehren solche RNG-Werte ausstream(...): macht daraus einen echtengen fn-artigen Datenstrom fuertake(...),for ... in ...,map(...)oderfilter(...)
Funktionen#
bindboolchooseconstantfixed_listfloatintint_steplist_genmap_gensampleseedshufflestepstreamtime_seeduniformweighted
fn bind(rng, f)Chains RNG values, where f receives the produced value and returns another RNG value.
Example:
import Antra::Random as Random
my chained = Random.bind(Random.int(1, 3), |n| -> Random.int(n, n + 10))
println(Random.step(chained, Random.seed(42))[0])fn bool()Returns an RNG value for true or false with equal probability.
Example:
import Antra::Random as Random
println(Random.step(Random.bool(), Random.seed(42))[0])fn choose(a, b)Returns an RNG value that chooses between a and b with equal probability.
fn constant(val)Returns an RNG value that always produces val and does not consume seed state.
Example:
import Antra::Random as Random
println(Random.step(Random.constant(99), Random.seed(42))[0])fn fixed_list(rng, n)Returns an RNG value that produces a list with exactly n values.
Example:
import Antra::Random as Random
println(Random.step(Random.fixed_list(Random.int(1, 6), 5), Random.seed(42))[0])fn float(from, to)Returns an RNG value for floating-point numbers in [from, to).
Example:
import Antra::Random as Random
println(Random.step(Random.float(0.0, 1.0), Random.seed(42))[0])fn int(from, to)Returns an RNG value for integers in [from, to].
Example:
import Antra::Random as Random
println(Random.step(Random.int(1, 6), Random.seed(42))[0])fn int_step(from, to, s)Fast path for integer sampling without constructing an RNG closure first.
Returns [value, next_seed] like step(int(from, to), seed), but is
better suited for tight interpreter loops.
Example:
import Antra::Random as Random
my [roll, next_seed] = Random.int_step(1, 6, Random.seed(42))
println(roll)fn list_gen(rng)Returns an RNG value that produces a list with random length from 0 to 32.
fn map_gen(rng, f)Maps the produced value of an RNG with f.
Example:
import Antra::Random as Random
my doubled = Random.map_gen(Random.int(1, 6), |n| -> n * 2)
println(Random.step(doubled, Random.seed(42))[0])fn sample(rng)Executes an RNG value with a time-based seed.
This is convenient, but intentionally not deterministic.
Example:
import Antra::Random as Random
println(Random.sample(Random.int(1, 6)))fn seed(n)Returns a deterministic seed value.
Example:
Random.seed(42)fn shuffle(list)Returns an RNG value that shuffles a list with Fisher-Yates.
Example:
import Antra::Random as Random
println(Random.step(Random.shuffle([1, 2, 3]), Random.seed(42))[0])fn step(rng, s)Executes an RNG value with an explicit seed.
Returns [value, next_seed].
Das ist die niedrigste, explizite Form der API: Du bekommst nicht nur
den aktuellen Wert, sondern auch den naechsten Seed zurueck. Wenn du
dieselbe Zufallsquelle weiterlaufen lassen willst, uebergibst du genau
diesen next_seed an den naechsten step(...)-Aufruf.
Example:
import Antra::Random as Random
my [roll, next_seed] = Random.step(Random.int(1, 6), Random.seed(42))
println(roll)
my [next_roll, third_seed] = Random.step(Random.int(1, 6), next_seed)
println(next_roll)gen fn stream(rng, s)Turns an RNG value plus a seed into a real gen fn-style generator.
Use this when you want to consume random values with take(...),
for ... in ..., map(...) or filter(...).
Example:
import Antra::Random as Random
my rolls = Random.stream(Random.int(1, 6), Random.seed(42))
println(take(rolls, 5))
for roll, i in Random.stream(Random.int(1, 6), Random.seed(42)) {
last if i >= 2
println(i <> ":" <> roll)
}fn time_seed()Returns a time-based seed for non-deterministic sampling.
Example:
Random.time_seed()fn uniform(list)Returns an RNG value that picks uniformly from a list.
fn weighted(pairs)Returns an RNG value for weighted choice.
pairs has the form [[weight, value], ...].
