Skuld.Effects.Random (skuld v0.2.3)
View SourceRandom effect - generate random values.
Provides three handler modes:
Production (
with_handler/1): Uses Erlang's:randmodule for cryptographically suitable random values.Seeded (
with_seed_handler/2): Uses a deterministic seed for reproducible random sequences - ideal for testing.Fixed (
with_fixed_handler/2): Returns values from a fixed sequence, cycling when exhausted - useful for specific test scenarios.
Production Usage
use Skuld.Syntax
alias Skuld.Comp
alias Skuld.Effects.Random
comp do
f <- Random.random()
i <- Random.random_int(1, 100)
elem <- Random.random_element([:a, :b, :c])
{f, i, elem}
end
|> Random.with_handler()
|> Comp.run!()
#=> {0.7234..., 42, :b}Seeded Usage (Deterministic)
# Same seed produces same sequence - reproducible tests
comp do
a <- Random.random()
b <- Random.random()
{a, b}
end
|> Random.with_seed_handler(seed: {1, 2, 3})
|> Comp.run!()
#=> {0.123..., 0.456...} # always the sameFixed Usage (Test Scenarios)
# Return specific values for testing edge cases
comp do
a <- Random.random()
b <- Random.random()
c <- Random.random()
{a, b, c}
end
|> Random.with_fixed_handler(values: [0.0, 0.5, 1.0])
|> Comp.run!()
#=> {0.0, 0.5, 1.0}Handler Submodules
Random.Seed- Deterministic seeded random handlerRandom.Fixed- Fixed value handler for testing
Summary
Functions
Install Random handler via catch clause syntax.
Generate a random float between 0.0 (inclusive) and 1.0 (exclusive).
Pick a random element from a non-empty list.
Generate a random integer in the range min..max (inclusive).
Shuffle a list randomly.
Install a handler that returns values from a fixed sequence.
Install a random handler using Erlang's :rand module.
Install a deterministic random handler with a fixed seed.
Functions
Install Random handler via catch clause syntax.
Config selects handler type:
catch
Random -> nil # production handler
Random -> {:seed, seed: {1, 2, 3}} # seeded handler
Random -> {:fixed, values: [0.5, 0.7]} # fixed values handler
@spec random() :: Skuld.Comp.Types.computation()
Generate a random float between 0.0 (inclusive) and 1.0 (exclusive).
Example
comp do
f <- Random.random()
f
end
|> Random.with_handler()
|> Comp.run!()
#=> 0.7234...
@spec random_element([a, ...]) :: Skuld.Comp.Types.computation() when a: term()
Pick a random element from a non-empty list.
Example
comp do
elem <- Random.random_element([:rock, :paper, :scissors])
elem
end
|> Random.with_handler()
|> Comp.run!()
#=> :scissors
@spec random_int(integer(), integer()) :: Skuld.Comp.Types.computation()
Generate a random integer in the range min..max (inclusive).
Example
comp do
i <- Random.random_int(1, 6)
i
end
|> Random.with_handler()
|> Comp.run!()
#=> 4
@spec shuffle([a]) :: Skuld.Comp.Types.computation() when a: term()
Shuffle a list randomly.
Example
comp do
shuffled <- Random.shuffle([1, 2, 3, 4, 5])
shuffled
end
|> Random.with_handler()
|> Comp.run!()
#=> [3, 1, 5, 2, 4]
@spec with_fixed_handler( Skuld.Comp.Types.computation(), keyword() ) :: Skuld.Comp.Types.computation()
Install a handler that returns values from a fixed sequence.
Delegates to Random.Fixed.with_handler/2.
Options
:values- A list of values to return. Forrandom()these should be floats 0.0-1.0. Forrandom_int/2andrandom_element/1, the handler uses these as indices (mod list length).
Example
comp do
a <- Random.random()
b <- Random.random()
c <- Random.random()
{a, b, c}
end
|> Random.with_fixed_handler(values: [0.1, 0.5, 0.9])
|> Comp.run!()
#=> {0.1, 0.5, 0.9}
@spec with_handler(Skuld.Comp.Types.computation()) :: Skuld.Comp.Types.computation()
Install a random handler using Erlang's :rand module.
Uses the default random algorithm seeded from system entropy. Not deterministic across runs.
Example
comp do
f <- Random.random()
f
end
|> Random.with_handler()
|> Comp.run!()
@spec with_seed_handler( Skuld.Comp.Types.computation(), keyword() ) :: Skuld.Comp.Types.computation()
Install a deterministic random handler with a fixed seed.
Delegates to Random.Seed.with_handler/2.
Options
:seed- A seed tuple{s1, s2, s3}for the random generator. Default:{1, 2, 3}.:algorithm- The random algorithm to use. Default::exsss.
Example
comp do
a <- Random.random()
b <- Random.random_int(1, 10)
{a, b}
end
|> Random.with_seed_handler(seed: {42, 42, 42})
|> Comp.run!()
#=> {0.123..., 7} # always the same with this seed