/* * Copyright 2024 Magnus Madsen * * Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE.md file. */pubmod Math.Random {use Math.Randomimport java.util.{Random => JRandom}////// An effect used to generate random numbers.///pubeffRandom {////// Returns a pseudorandom 64-bit floating-point number in the range [0.0, 1.0].///defrandomFloat64(): Float64////// Returns a pseudorandom 64-bit integer.///defrandomInt64(): Int64 }////// Handles the `Random` effect of the given function `f`.////// In other words, re-interprets the `Random` effect using the `IO` effects.///pubdefhandle(f: a -> b \ ef): a -> b \ (ef - Random) + IO =x -> {letrnd = new JRandom(); // Reuse Random instance.run {f(x) } withhandlerRandom {defrandomFloat64(k) = k(rnd.nextDouble())defrandomInt64(k) = k(rnd.nextLong()) } }////// Runs the `Random` effect of the given function `f`.////// In other words, re-interprets the `Random` effect using the `IO` effects.///@DefaultHandlerpubdefrunWithIO(f: Unit -> a \ ef): a \ (ef - Random) + IO = handle(f)()////// Runs the `Random` effect of the given function `f` from an initial seed.////// In other words, re-interprets the `Random` effect using seeded deterministic randomness.///pubdefhandleWithSeed(seed: Int64, f: a -> b \ ef): a -> b \ ef - Random =// Note: Given a *specific* seed, JRandom is fully deterministic (i.e. pure).x -> {letrnd = unsafeIO { new JRandom(seed) };run {f(x) } withhandlerRandom {defrandomFloat64(k) = k(unsafeIO { rnd.nextDouble() })defrandomInt64(k) = k(unsafeIO { rnd.nextLong() }) } }////// Runs the `Random` effect of the given function `f` from an initial seed.////// In other words, re-interprets the `Random` effect using seeded deterministic randomness.///pubdefrunWithSeed(seed: Int64, f: Unit -> a \ ef): a \ ef - Random = handleWithSeed(seed, f)()}