Skip to content

Commit

Permalink
Merge pull request #1720 from patseev/remove-assertions
Browse files Browse the repository at this point in the history
Use raiseError instead of assertions in Random
  • Loading branch information
djspiewak committed Feb 27, 2021
2 parents 3f18865 + 8ea26a4 commit f69c134
Showing 1 changed file with 47 additions and 46 deletions.
93 changes: 47 additions & 46 deletions std/shared/src/main/scala/cats/effect/std/Random.scala
Original file line number Diff line number Diff line change
Expand Up @@ -210,71 +210,69 @@ object Random {

private abstract class ScalaRandom[F[_]: Sync](f: F[SRandom]) extends Random[F] {

def betweenLong(minInclusive: Long, maxExclusive: Long): F[Long] = {
require(minInclusive < maxExclusive, "Invalid bounds")
val difference = maxExclusive - minInclusive
for {
out <-
if (difference >= 0) {
nextLongBounded(difference).map(_ + minInclusive)
} else {
/* The interval size here is greater than Long.MaxValue,
* so the loop will exit with a probability of at least 1/2.
*/
def loop(): F[Long] = {
nextLong.flatMap { n =>
if (n >= minInclusive && n < maxExclusive) n.pure[F]
else loop()
def betweenLong(minInclusive: Long, maxExclusive: Long): F[Long] =
require(minInclusive < maxExclusive, "Invalid bounds") *> {
val difference = maxExclusive - minInclusive
for {
out <-
if (difference >= 0) {
nextLongBounded(difference).map(_ + minInclusive)
} else {
/* The interval size here is greater than Long.MaxValue,
* so the loop will exit with a probability of at least 1/2.
*/
def loop(): F[Long] = {
nextLong.flatMap { n =>
if (n >= minInclusive && n < maxExclusive) n.pure[F]
else loop()
}
}
loop()
}
loop()
}
} yield out
}
} yield out
}

def betweenInt(minInclusive: Int, maxExclusive: Int): F[Int] = {
require(minInclusive < maxExclusive, "Invalid bounds")
val difference = maxExclusive - minInclusive
for {
out <-
if (difference >= 0) {
nextIntBounded(difference).map(_ + minInclusive)
} else {
/* The interval size here is greater than Int.MaxValue,
* so the loop will exit with a probability of at least 1/2.
*/
def loop(): F[Int] = {
nextInt.flatMap { n =>
if (n >= minInclusive && n < maxExclusive) n.pure[F]
else loop()
def betweenInt(minInclusive: Int, maxExclusive: Int): F[Int] =
require(minInclusive < maxExclusive, "Invalid bounds") *> {
val difference = maxExclusive - minInclusive
for {
out <-
if (difference >= 0) {
nextIntBounded(difference).map(_ + minInclusive)
} else {
/* The interval size here is greater than Int.MaxValue,
* so the loop will exit with a probability of at least 1/2.
*/
def loop(): F[Int] = {
nextInt.flatMap { n =>
if (n >= minInclusive && n < maxExclusive) n.pure[F]
else loop()
}
}
loop()
}
loop()
}
} yield out
}
} yield out
}

def betweenFloat(minInclusive: Float, maxExclusive: Float): F[Float] = {
require(minInclusive < maxExclusive, "Invalid bounds")
def betweenFloat(minInclusive: Float, maxExclusive: Float): F[Float] =
for {
_ <- require(minInclusive < maxExclusive, "Invalid bounds")
f <- nextFloat
} yield {
val next = f * (maxExclusive - minInclusive) + minInclusive
if (next < maxExclusive) next
else Math.nextAfter(maxExclusive, Float.NegativeInfinity)
}
}

def betweenDouble(minInclusive: Double, maxExclusive: Double): F[Double] = {
require(minInclusive < maxExclusive, "Invalid bounds")
def betweenDouble(minInclusive: Double, maxExclusive: Double): F[Double] =
for {
_ <- require(minInclusive < maxExclusive, "Invalid bounds")
d <- nextDouble
} yield {
val next = d * (maxExclusive - minInclusive) + minInclusive
if (next < maxExclusive) next
else Math.nextAfter(maxExclusive, Double.NegativeInfinity)
}
}

def nextAlphaNumeric: F[Char] = {
val chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
Expand Down Expand Up @@ -331,8 +329,6 @@ object Random {
} yield out

def nextLongBounded(n: Long): F[Long] = {
require(n > 0, "n must be positive")

/*
* Divide n by two until small enough for nextInt. On each
* iteration (at most 31 of them but usually much less),
Expand All @@ -341,6 +337,7 @@ object Random {
* half (which makes a difference only if odd).
*/
for {
_ <- require(n > 0, s"n must be positive, but was $n")
offset <- Ref[F].of(0L)
_n <- Ref[F].of(n)
_ <- Monad[F].whileM_(_n.get.map(_ >= Integer.MAX_VALUE))(
Expand Down Expand Up @@ -382,5 +379,9 @@ object Random {
r <- f
out <- Sync[F].delay(r.shuffle(v))
} yield out

private def require(condition: Boolean, errorMessage: => String): F[Unit] =
if (condition) ().pure[F]
else new IllegalArgumentException(errorMessage).raiseError[F, Unit]
}
}

0 comments on commit f69c134

Please sign in to comment.