Current section

Files

Jump to
prng src prng@random.erl
Raw

src/prng@random.erl

-module(prng@random).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([step/2, sample/2, to_yielder/2, to_random_yielder/1, random_sample/1, int/2, float/2, constant/1, fixed_size_list/2, then/2, list/1, map/2, weighted/2, try_weighted/1, map2/3, pair/2, uniform/2, try_uniform/1, choose/2, map3/4, map4/5, map5/6, fixed_size_string/1, string/0, bit_array/0, set/1, fixed_size_set/2, dict/2, fixed_size_dict/3]).
-export_type([generator/1]).
-opaque generator(GIJ) :: {generator,
fun((prng@seed:seed()) -> {GIJ, prng@seed:seed()})}.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 154).
-spec step(generator(GIK), prng@seed:seed()) -> {GIK, prng@seed:seed()}.
step(Generator, Seed) ->
(erlang:element(2, Generator))(Seed).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 164).
-spec sample(generator(GIM), prng@seed:seed()) -> GIM.
sample(Generator, Seed) ->
erlang:element(1, step(Generator, Seed)).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 224).
-spec to_yielder(generator(GIT), prng@seed:seed()) -> gleam@yielder:yielder(GIT).
to_yielder(Generator, Seed) ->
gleam@yielder:unfold(
Seed,
fun(Seed@1) ->
{Value, New_seed} = step(Generator, Seed@1),
{next, Value, New_seed}
end
).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 210).
-spec to_random_yielder(generator(GIQ)) -> gleam@yielder:yielder(GIQ).
to_random_yielder(Generator) ->
to_yielder(Generator, prng@seed:random()).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 191).
-spec random_sample(generator(GIO)) -> GIO.
random_sample(Generator) ->
_assert_subject = gleam@yielder:first(to_random_yielder(Generator)),
{ok, Result} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"prng/random"/utf8>>,
function => <<"random_sample"/utf8>>,
line => 196})
end,
Result.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 264).
-spec sort_ascending(GIX, GIX, fun((GIX, GIX) -> gleam@order:order())) -> {GIX,
GIX}.
sort_ascending(One, Other, Compare) ->
case Compare(One, Other) of
lt ->
{One, Other};
eq ->
{One, Other};
gt ->
{Other, One}
end.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 258).
-spec int(integer(), integer()) -> generator(integer()).
int(From, To) ->
{generator,
fun(Seed) ->
{Low, High} = sort_ascending(From, To, fun gleam@int:compare/2),
prng_ffi:random_int(Seed, Low, High)
end}.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 283).
-spec float(float(), float()) -> generator(float()).
float(From, To) ->
{generator,
fun(Seed) ->
{Low, High} = sort_ascending(From, To, fun gleam@float:compare/2),
prng_ffi:random_float(Seed, Low, High)
end}.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 305).
-spec constant(GIZ) -> generator(GIZ).
constant(Value) ->
{generator, fun(Seed) -> {Value, Seed} end}.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 465).
-spec get_by_weight({float(), GJR}, list({float(), GJR}), float()) -> GJR.
get_by_weight(First, Others, Countdown) ->
{Weight, Value} = First,
case Others of
[] ->
Value;
[Second | Rest] ->
Positive_weight = gleam@float:absolute_value(Weight),
case gleam@float:compare(Countdown, Positive_weight) of
lt ->
Value;
eq ->
Value;
gt ->
get_by_weight(Second, Rest, Countdown - Positive_weight)
end
end.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 552).
-spec do_fixed_size_list(list(GKE), prng@seed:seed(), generator(GKE), integer()) -> {list(GKE),
prng@seed:seed()}.
do_fixed_size_list(Acc, Seed, Generator, Length) ->
case Length =< 0 of
true ->
{Acc, Seed};
false ->
{Value, Seed@1} = step(Generator, Seed),
do_fixed_size_list([Value | Acc], Seed@1, Generator, Length - 1)
end.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 544).
-spec fixed_size_list(generator(GKA), integer()) -> generator(list(GKA)).
fixed_size_list(Generator, Length) ->
{generator,
fun(Seed) -> do_fixed_size_list([], Seed, Generator, Length) end}.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 746).
-spec then(generator(GLT), fun((GLT) -> generator(GLV))) -> generator(GLV).
then(Generator, Generator_from) ->
{generator,
fun(Seed) ->
{Value, Seed@1} = step(Generator, Seed),
_pipe = Generator_from(Value),
step(_pipe, Seed@1)
end}.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 573).
-spec list(generator(GKI)) -> generator(list(GKI)).
list(Generator) ->
then(int(0, 32), fun(Size) -> fixed_size_list(Generator, Size) end).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 773).
-spec map(generator(GLY), fun((GLY) -> GMA)) -> generator(GMA).
map(Generator, Fun) ->
{generator,
fun(Seed) ->
{Value, Seed@1} = step(Generator, Seed),
{Fun(Value), Seed@1}
end}.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 420).
-spec weighted({float(), GJJ}, list({float(), GJJ})) -> generator(GJJ).
weighted(First, Others) ->
Normalise = fun(Pair) ->
gleam@float:absolute_value(gleam@pair:first(Pair))
end,
Total = Normalise(First) + gleam@float:sum(
gleam@list:map(Others, Normalise)
),
map(
float(+0.0, Total),
fun(_capture) -> get_by_weight(First, Others, _capture) end
).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 458).
-spec try_weighted(list({float(), GJM})) -> {ok, generator(GJM)} | {error, nil}.
try_weighted(Options) ->
case Options of
[First | Rest] ->
{ok, weighted(First, Rest)};
[] ->
{error, nil}
end.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 817).
-spec map2(generator(GMC), generator(GME), fun((GMC, GME) -> GMG)) -> generator(GMG).
map2(One, Other, Fun) ->
{generator,
fun(Seed) ->
{A, Seed@1} = step(One, Seed),
{B, Seed@2} = step(Other, Seed@1),
{Fun(A, B), Seed@2}
end}.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 525).
-spec pair(generator(GJV), generator(GJX)) -> generator({GJV, GJX}).
pair(One, Other) ->
map2(One, Other, fun gleam@pair:new/2).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 342).
-spec uniform(GJB, list(GJB)) -> generator(GJB).
uniform(First, Others) ->
weighted(
{1.0, First},
gleam@list:map(
Others,
fun(_capture) -> gleam@pair:new(1.0, _capture) end
)
).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 378).
-spec try_uniform(list(GJE)) -> {ok, generator(GJE)} | {error, nil}.
try_uniform(Options) ->
case Options of
[First | Rest] ->
{ok, uniform(First, Rest)};
[] ->
{error, nil}
end.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 505).
-spec choose(GJT, GJT) -> generator(GJT).
choose(One, Other) ->
uniform(One, [Other]).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 861).
-spec map3(
generator(GMI),
generator(GMK),
generator(GMM),
fun((GMI, GMK, GMM) -> GMO)
) -> generator(GMO).
map3(One, Two, Three, Fun) ->
{generator,
fun(Seed) ->
{A, Seed@1} = step(One, Seed),
{B, Seed@2} = step(Two, Seed@1),
{C, Seed@3} = step(Three, Seed@2),
{Fun(A, B, C), Seed@3}
end}.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 878).
-spec map4(
generator(GMQ),
generator(GMS),
generator(GMU),
generator(GMW),
fun((GMQ, GMS, GMU, GMW) -> GMY)
) -> generator(GMY).
map4(One, Two, Three, Four, Fun) ->
{generator,
fun(Seed) ->
{A, Seed@1} = step(One, Seed),
{B, Seed@2} = step(Two, Seed@1),
{C, Seed@3} = step(Three, Seed@2),
{D, Seed@4} = step(Four, Seed@3),
{Fun(A, B, C, D), Seed@4}
end}.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 900).
-spec map5(
generator(GNA),
generator(GNC),
generator(GNE),
generator(GNG),
generator(GNI),
fun((GNA, GNC, GNE, GNG, GNI) -> GNK)
) -> generator(GNK).
map5(One, Two, Three, Four, Five, Fun) ->
{generator,
fun(Seed) ->
{A, Seed@1} = step(One, Seed),
{B, Seed@2} = step(Two, Seed@1),
{C, Seed@3} = step(Three, Seed@2),
{D, Seed@4} = step(Four, Seed@3),
{E, Seed@5} = step(Five, Seed@4),
{Fun(A, B, C, D, E), Seed@5}
end}.
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 937).
-spec fixed_size_string(integer()) -> generator(binary()).
fixed_size_string(Size) ->
_pipe = fixed_size_list(utf_codepoint_in_range(0, 1023), Size),
map(_pipe, fun gleam_stdlib:utf_codepoint_list_to_string/1).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 925).
-spec string() -> generator(binary()).
string() ->
then(int(0, 32), fun(Size) -> fixed_size_string(Size) end).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 706).
-spec bit_array() -> generator(bitstring()).
bit_array() ->
map(string(), fun gleam_stdlib:identity/1).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 948).
-spec utf_codepoint_in_range(integer(), integer()) -> generator(integer()).
utf_codepoint_in_range(Lower, Upper) ->
then(
int(Lower, Upper),
fun(Raw_codepoint) -> case gleam@string:utf_codepoint(Raw_codepoint) of
{ok, Codepoint} ->
constant(Codepoint);
{error, _} ->
utf_codepoint_in_range(Lower, Upper)
end end
).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 699).
-spec set(generator(GLO)) -> generator(gleam@set:set(GLO)).
set(Generator) ->
then(int(0, 32), fun(Size) -> fixed_size_set(Generator, Size) end).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 651).
-spec fixed_size_set(generator(GLF), integer()) -> generator(gleam@set:set(GLF)).
fixed_size_set(Generator, Size) ->
_pipe = gleam@int:max(Size, 0),
do_fixed_size_set(Generator, _pipe, 0, 0, gleam@set:new()).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 659).
-spec do_fixed_size_set(
generator(GLJ),
integer(),
integer(),
integer(),
gleam@set:set(GLJ)
) -> generator(gleam@set:set(GLJ)).
do_fixed_size_set(Generator, Size, Unique_items, Consecutive_attempts, Acc) ->
Has_required_size = Unique_items =:= Size,
gleam@bool:guard(
Has_required_size,
constant(Acc),
fun() ->
Has_reached_maximum_attempts = Consecutive_attempts >= 10,
gleam@bool:guard(
Has_reached_maximum_attempts,
constant(Acc),
fun() ->
then(
Generator,
fun(Item) -> case gleam@set:contains(Acc, Item) of
true ->
_pipe = (Consecutive_attempts + 1),
do_fixed_size_set(
Generator,
Size,
Unique_items,
_pipe,
Acc
);
false ->
_pipe@1 = gleam@set:insert(Acc, Item),
do_fixed_size_set(
Generator,
Size,
Unique_items + 1,
0,
_pipe@1
)
end end
)
end
)
end
).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 639).
-spec dict(generator(any()), generator(any())) -> generator(gleam@dict:dict(any(), any())).
dict(Keys, Values) ->
then(int(0, 32), fun(Size) -> fixed_size_dict(Keys, Values, Size) end).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 588).
-spec fixed_size_dict(generator(GKM), generator(GKO), integer()) -> generator(gleam@dict:dict(GKM, GKO)).
fixed_size_dict(Keys, Values, Size) ->
_pipe = gleam@int:max(Size, 0),
do_fixed_size_dict(Keys, Values, _pipe, 0, 0, maps:new()).
-file("/Users/giacomocavalieri/Documents/progetti/prng/src/prng/random.gleam", 597).
-spec do_fixed_size_dict(
generator(GKR),
generator(GKT),
integer(),
integer(),
integer(),
gleam@dict:dict(GKR, GKT)
) -> generator(gleam@dict:dict(GKR, GKT)).
do_fixed_size_dict(Keys, Values, Size, Unique_keys, Consecutive_attempts, Acc) ->
Has_required_size = Unique_keys =:= Size,
gleam@bool:guard(
Has_required_size,
constant(Acc),
fun() ->
Has_reached_maximum_attempts = Consecutive_attempts >= 10,
gleam@bool:guard(
Has_reached_maximum_attempts,
constant(Acc),
fun() ->
then(Keys, fun(Key) -> case gleam@dict:has_key(Acc, Key) of
true ->
_pipe = (Consecutive_attempts + 1),
do_fixed_size_dict(
Keys,
Values,
Size,
Unique_keys,
_pipe,
Acc
);
false ->
then(
Values,
fun(Value) ->
_pipe@1 = gleam@dict:insert(
Acc,
Key,
Value
),
do_fixed_size_dict(
Keys,
Values,
Size,
Unique_keys + 1,
0,
_pipe@1
)
end
)
end end)
end
)
end
).