Skuld.Effects.Random (skuld v0.23.0)

View Source

Random effect - generate random values.

Provides three handler modes:

  • Production (with_handler/1): Uses Erlang's :rand module 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 same

Fixed 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 handler
  • Random.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

__handle__(comp, arg2)

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

with_fixed_handler(comp, opts \\ [])

@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. For random() these should be floats 0.0-1.0. For random_int/2 and random_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}

with_handler(comp)

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!()

with_seed_handler(comp, opts \\ [])

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