I agree with @Lucas_Payr. I think that having a native solution would be imperfect in a lot of situations, like if you wanted to model numbers that fulfill other conditions (even or odd, inside a (in)finite set of numbers like {1, 2, 3, 5, 8, 11, …}).
I think that this check is best done in custom code, therefore in a custom opaque type.
You’ll have to deal with a lot of safeguards (functions that return Maybe
s in case your value doesn’t match the conditions), but I think that that can be simplified when something is easily detectable through static analysis, as I described in safe unsafe operations in Elm.