A number type with a limited number of values

Hi everyone,

In our Coding Dojo, we're currently practicing Object Calisthenics. One of the rules is:

  1. Wrap all primitives and strings (wrap primitive types in classes)

I'm practicing this on the "Greed is Good" kata, which is about scores from dice rolls.

Off course, I could model a diceroll as
let roll = 5 // inferred to be Int
but this violates the mentioned rule.

I would prefer to have an actual DiceRoll type that acts like a number (i.e. so you can add them for instance), but also is limited to values 1...6.

I now have an enum representing this type:

enum DiceThrow {
    case one
    case two
    case three
    case four
    case five
    case six

    init?(_ intValue: Int) {
        switch intValue {
        case 1:
        self = .one
        case 2:
        self = .two
        case 3:
        self = .three
        case 4:
        self = .four
        case 5:
        self = .five
        case 6:
        self = .six
        default:
            return nil
        }
    }
}

My question is: is there a number type in Swift here I can limit the values to a specific range?

And if not, what is the best practice to represent something like this?

Ideally, I would have compiler support that does not let me express invalid values. I.e.:
let roll = DiceRoll(7) // Compile error
But this is more of a 'bonus' than a necessity.

1 Like

:eyes: (interesting...)

Wasn't one of the demos in the Property Wrapper pitch 'clamped', which limits numbers to a range?

2 Likes

The best practice for representing what you now have is with a raw value, which does exactly the same as your initialiser even returning nil when you feed it a value out of range:

enum DiceThrow: Int {
	case one = 1
	case two
	case three
	case four
	case five
	case six
}

let roll = DiceThrow(rawValue: 7)
4 Likes

Nice! I'll check that one.
Thank you for pointing me in the right direction. :pray: