I am looking for a nice way to represent a numeric type that is constrained via runtime configuration. Example: Pagination of search results. The maximum page size, psMax
(> 0), is given in the service configuration, the actual page size ps
(with psMax
>= ps
> 0) is specified by the client. In the spirit of “parse, don’t validate”, I’d like to have a dedicated type (be it a generic “bounded positive int” or a specific “page size”) that represents legal values of this kind.
Independent of the implementation mechanism (plain case class, Shapeless tagged type, refined, Scala 3 opaque type,…), I see these options:
- Plain
PageSize
without any reference to the max constraint whatsoever. This would become brittle in a system with multiple pagination settings - e.g. page sizes for “overview” with a max of 50 results could not be distinguished from page sizes for “details” with a max of 10 results. - Plain
PageSize
without any reference to the max constraint at the type level, but with a value level reference to the max constraint. Any validation/enforcement could only happen at value level/runtime, as well. PageSize[Max <: Int]
with a literal type. This could nicely enforce matching a correspondingPaginationConfig[Max <: Int]
It feels like this approach would ultimately require this type parameter across the whole code base, which is inconvenient in itself and certainly won’t scale to many types of this kind.PageSize { type Max <: Int }
. Frankly, I don’t have much of an idea how I could get the type member to actually document/enforce anything about the max constraint. For now, just listing it here for the sake of completeness.- Anything else…?
Any suggestions, pointers to prior art, etc. appreciated.