## Range

Range represents a range [x, y] that can be generated by using discrete operations Discrete.

## Supported Operations

• start: starting value of Range.
• end: ending value of Range.
• toList: returns all the values in the Range as a List.
• contains(value): verifies value is within the Range.
• contains(range): verifies range is within the Range.
• reverse: returns the reverted range Range [end, start]
• -(other): Calculate the difference with Range.
• It returns a tuple with the difference to the right and to the left of Range.
• It basically calculates what is to the left of other that is in Range and what is to the right of other that is in Range (in both cases it does not include elements in other)
• toString: returns

## Inverted Range

Note that if x > y and we create the range [x, y] it will be treated as the inverted range [y, x].

## Using Range

We can get the values from a range using generate or toList functions. We can also get the string representing the range in math notation. Range(x, y) is represented by [x, y] and Range.empty is represented by [] by using cats.Show

import cats._, cats.implicits._, cats.collections._, cats.collections.syntax.all._, cats.collections.Range._

val range = Range(1, 10)
// range: Range[Int] = Range(start = 1, end = 10)
range.show
// res0: String = "[1, 10]"

range.toList
// res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

We can get the inverted range using the reverse functions

range.reverse.show
// res2: String = "[10, 1]"

Asking for start and end on a Range

val range = Range(1, 10)
// range: Range[Int] = Range(start = 1, end = 10)
range.start
// res3: Int = 1
range.end
// res4: Int = 10

Asking for a value within Range

val range = Range(1, 10)
// range: Range[Int] = Range(start = 1, end = 10)
range.contains(5)
// res5: Boolean = true

Asking for a value that is not within Range

val range = Range(1, 10)
// range: Range[Int] = Range(start = 1, end = 10)
range.contains(20)
// res6: Boolean = false

Asking for the difference between two Ranges returns 0, 1, or 2 result ranges

val range = Range(1, 10)
// range: Range[Int] = Range(start = 1, end = 10)
Range(10, 20).show
// res7: String = "[10, 20]"
(range - Range(5, 9)).show
// res8: String = "Some(([1, 4],Some([10, 10])))"
(range - Range(30, 40)).show
// res9: String = "Some(([1, 10],None))"
(range - Range(15, 18)).show
// res10: String = "Some(([1, 10],None))"
(range - Range (5, 30)).show
// res11: String = "Some(([1, 4],None))"

Creating an inverted range

val range = Range(50, 20)
// range: Range[Int] = Range(start = 50, end = 20)

range.toList
// res12: List[Int] = List(
//   50,
//   49,
//   48,
//   47,
//   46,
//   45,
//   44,
//   43,
//   42,
//   41,
//   40,
//   39,
//   38,
//   37,
//   36,
//   35,
//   34,
//   33,
//   32,
//   31,
//   30,
//   29,
//   28,
//   27,
//   26,
//   25,
//   24,
//   23,
//   22,
//   21,
//   20
// )

The reverse of a range should be its inverted range

val range = Range(20, 30)
// range: Range[Int] = Range(start = 20, end = 30)
range.show
// res13: String = "[20, 30]"

val other = Range(30, 20)
// other: Range[Int] = Range(start = 30, end = 20)
other.show
// res14: String = "[30, 20]"

range.reverse.toList == other.toList
// res15: Boolean = true