Skip to main content
Version: 2.x

Random

Random service provides utilities to generate random numbers. It's a functional wrapper of scala.util.Random. It follows the shared service pattern common to all of ZIO's built-in services: a Random trait, a Live implementation, and a synchronous UnsafeAPI for interop. Every method returns UIO[A] and cannot fail.

FunctionInput TypeOutput Type
nextBooleanUIO[Boolean]
nextByteslength: IntUIO[Chunk[Byte]]
nextDoubleUIO[Double]
nextDoubleBetweenminInclusive: Double, maxExclusive: DoubleUIO[Double]
nextFloatUIO[Float]
nextFloatBetweenminInclusive: Float, maxExclusive: FloatUIO[Float]
nextGaussianUIO[Double]
nextIntUIO[Int]
nextIntBetweenminInclusive: Int, maxExclusive: IntUIO[Int]
nextIntBoundedn: IntUIO[Int]
nextLongUIO[Long]
nextLongBetweenminInclusive: Long, maxExclusive: LongUIO[Long]
nextLongBoundedn: LongUIO[Long]
nextPrintableCharUIO[Char]
nextStringlength: IntUIO[String]
nextUUIDUIO[UUID]
setSeedseed: LongUIO[Unit]
shufflecollection: Collection[A]UIO[Collection[A]]
import zio._

for {
randomInt <- Random.nextInt
_ <- Console.printLine(s"A random Int: $randomInt")
randomChar <- Random.nextPrintableChar
_ <- Console.printLine(s"A random Char: $randomChar")
randomDouble <- Random.nextDoubleBetween(1.0, 5.0)
_ <- Console.printLine(s"A random double between 1.0 and 5.0: $randomDouble")
} yield ()

Random service has a setSeed which helps us to alter the state of the random generator. It is useful for setting up a test version of Random service when we need to reproduce always the same sequence of numbers.

import zio._

for {
_ <- Random.setSeed(0)
nextInts <- (Random.nextInt zip Random.nextInt)
} yield assert(nextInts == (-1155484576,-723955400))

The bounded and "between" variants (nextIntBounded, nextIntBetween, and their Long/Float/Double counterparts) exclude their upper bound — nextIntBetween(0, 6) never returns 6, the same convention as nextInt(6) on scala.util.Random. nextBytes returns a Chunk[Byte] rather than an Array[Byte], keeping the result immutable and consistent with the rest of ZIO's collection types.

On the Random trait, shuffle is generic over any Collection[A] <: Iterable[A], rebuilding the same collection type using an implicit BuildFrom, and runs a Fisher-Yates shuffle internally; the top-level Random.shuffle accessor specializes this to List[A]. nextGaussian returns the next pseudorandom, Gaussian ("normally") distributed double value with mean 0.0 and standard deviation 1.0:

import zio._

val shuffledList: UIO[List[Int]] = Random.shuffle(List(1, 2, 3, 4, 5))

Note:

Random numbers that are generated via Random service are not cryptographically strong. Therefore it's not safe to use the ZIO Random service for security domains where a high level of security and randomness is required, such as password generation.

RandomScala​

Besides the default RandomLive implementation, which delegates to Scala's global scala.util.Random, Random.RandomScala wraps a caller-supplied scala.util.Random instance instead. It implements the same Random trait, so it's useful when you need a specific, seeded scala.util.Random instance — for example to obtain a reproducible sequence outside of tests, without going through TestRandom:

import zio._

val customRandom: Random = Random.RandomScala(new scala.util.Random(42L))

Synchronous Access (unsafe)​

Random also exposes a synchronous UnsafeAPI, following the pattern described in Anatomy of a Built-in Service. RandomLive's unsafe implementation delegates directly to the corresponding method on scala.util.Random (nextBoolean(), nextInt(), nextGaussian(), and so on), without running an effect:

import zio._

Unsafe.unsafe { implicit unsafe =>
val n: Int = Random.RandomLive.unsafe.nextInt()
}

Prefer the ordinary Random.nextInt-style accessors everywhere else.

Testing Randomness​

TestRandom lets tests either feed predetermined sequences of values or use a deterministic pseudo-random generator instead of the live, unseeded generator. See Testing Random for its feed*/clear* API.

See Also​

  • Built-in Services — Overview of ZIO's built-in services including Console, Clock, Random, and System that provide common functionality without explicit environment setup.