# What is the use case of Integral[T] trait in Scala?

I was looking into `NumericRange` class in Scala. And I found that every floating point number has to be converted into `BigDecimal` to be used in a `NumericRange` data structure.

This is the stackoverflow question I asked - https://stackoverflow.com/questions/74762743/what-is-the-difference-between-generating-range-and-numericrange-in-scala

As the answer suggests, `BigDecimal` values consists of `Integral[T]`s, while other floating point numeric types do not.

But my question is what is the use case of `Integral[T]` in Scala? What does it means for a number to be integral?

I tried to find the answer on my own, and most sources say integral numbers are similar to integers. But it seems like thatâ€™s not the case in Scala. Please help me.

You are correct, integral numbers are whole numbers, and `BigDecimal` doesnâ€™t qualify as an integral number. Looks like this is just cheating, precisely in order to make numeric ranges applicable with `BigDecimal`. I donâ€™t know the reasoning behind this design choice, but it feels fishy.

While other proper `Integral` impls are named `XYIsIntegral`, the `BigDecimal` one is called `BigDecimalAsIfIntegral`, annotated with a comment

``````// For BigDecimal we offer an implicit Fractional object, but also one
// which acts like an Integral type, which is useful in NumericRange.
``````
1 Like
``````  // BigDecimal uses an alternative implementation of Numeric in which
// it pretends to be Integral[T] instead of Fractional[T].  See Numeric for
// details.  The intention is for it to throw an exception anytime
// imprecision or surprises might result from anything, although this may
// not yet be fully implemented.
``````
1 Like

@LSampath

Hereâ€™s the documentation NumericRange It says

`NumericRange` is a more generic version of the `Range` class which works with arbitrary types. It must be supplied with an `Integral` implementation of the range type.

If we look at the source code here for `NumericRange` scala/NumericRange.scala at v2.13.8 Â· scala/scala Â· GitHub we can see that `quot` is used, which means it has to be provided. (Interestingly `rem` is not used! At least not there. Probably used in other places that require `Integral[T]`.)

As you can see here from the initial part of the code

``````@SerialVersionUID(3L)
sealed class NumericRange[T](
val start: T,
val end: T,
val step: T,
val isInclusive: Boolean
)(implicit
num: Integral[T]
)
``````

an implicit value of type `Integral[T]` must be present for it to work. Implicits of Scala 2 and typeclasses of Haskell (and of Scala 3) both implement the same idea: ad-hoc polymorphism.

So itâ€™s not about a `BigDecimal` itself being â€śinteger-likeâ€ť, itâ€™s about the range-like functionality that needs an â€śinteger-likeâ€ť thing (the implicit value) to work. The `quot` (and possibly the `rem`) methods of the implicit value are used in the generation of ranges. If you donâ€™t know/understand implicits or typeclasses this will be confusing for you.

If we keep reading the comments in the source code it says:

Factories for likely types include Range.BigInt, Range.Long, and Range.BigDecimal. Range.Int exists for completeness

So `Range` functionality is made specially for `BigDecimal` but not `Double`. Iâ€™m sure there are some reasons for this.

But these are all technical implementation details that we shouldnâ€™t worry about.

You really shouldnâ€™t be thinking too much about this stuff. Especially if you are new to Scala. Just use it, you donâ€™t need to understand how itâ€™s implemented under the hood.

DO NOT waste your time trying to find answers to these kinds of questions on your own. Get the book Programming in Scala, Fifth Edition Resources which explains every type in detail. Or take the online classes Online Courses (MOOCs) from The Scala Center | Scala Documentation I see newcomers keep wasting so much time with web searches, StackOverflows, tutorials etc. Just go straight to the source made by the language creators.

1 Like

@sangamon Thanks for help.

@spamegg1
You are correct. I am a newbie to Scala, coming from Java. Thanks for help. Now I need to look into `implicits`.

The issue is that if you use a standard `Double` or `Float`, then the range length is not guaranteed due to rounding errors. Their was quite a bit of discussion on this.