Today, I learned about how decks of playing cards can have all kinds of confusing stuff going on when they're not the "standard" deck. I vaguely knew about this from playing Zachtronics games, but it seems like what I've seen there so far is just scratching the surface.
In any case, I spent the day iterating on representing playing cards in a way that works more like an ordered set than the options that were more obvious to me. Those options would have introduced many run-time distinctions that I would consider basically meaningless. The implementation is, at a type level, extremely cursed, but it resolves down to really simple data at runtime.
The practical benefit of this is that I can extract an ordering of cards from the type that describes them, but the actual instances are also instances of a type with the same cards in a different order. I haven't checked, but I assume these rearrangements are indistinguishable from a static analysis perspective. The really nice thing is that it's still the same cards if I have a deck that drops some, or if I add the same cards to two different decks.
So, the initial prototyping went well, and what I want to focus on now is writing up a specification for every deck I try to model, because some of the prototypes came out a little wrong, now that I understand my system better.
I'll wrap up for now and work on documenting stuff tomorrow.