Skuld.Effects.Random (skuld v0.23.0)
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.
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 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