Pre-defining type constraints like this is akin conceptually to defining
subtypes. If you want to do this at a level which is conceptually generic
and intended to be widely used, you need to have more generic thinking than
some of the examples suggest.
I'll suggest some alternatives here:
John Napiorkowski wrote:
Item[
Default
]
Bool
Maybe[`a]
Undef
Defined
Value[
IsOneOf||Enum
You should also add an IsNotOneOf.
]
Num[
LessThanOrEqual || '<='
LessThan || '<'
GreaterThanOrEqual || '>='
GreaterThan || '>'
First, all of these above 4 constraints should be applicable to any ordered
type, not just Num; you should also be able to use them on Int and Str at
least. Or considering the context, Int and Str should have their own
versions of these, so say, name them [NumLessThan, IntLessThan,
StrLessThan]. Maybe also have versions for Bool for simple determinism;
False is ordered before True; or maybe that's overkill.
Next, to aid code brevity, you should add Between and NotBetween
constraints, which takes 2 boundary parameters to test the constrained
value against. Or have it take 4 parameters, where the extra 2 say whether
each boundary value is inclusive or exclusive. Or have separate Incl/Excl
versions of the constraints, or something. Likewise these should work with
all ordered types.
For example:
NumBetween[32,Incl,212,Excl]
EqualTo || '='
The above 1 constraint I see limited utility for since then you've
effectively declared a constant. But perhaps a NotEqualTo constraint would
have more utility. If either exists, every type should have one.
Precision
Scale
These have a problem of being, on the face of it, radix-specific. You
should generalize those into versions that also have radix parameters,
where 2 and 10 are likely the most common values; or maybe you already had
a radix parameter in mind.
]
Int[
Signed
Signed has no purpose as it would allow all Int and is redundant; unless
this was meant to be parameterized.
UnSigned
I would also add Positive to this list. If they're not parameterized, then
ditch Signed and add Int to these names, maybe abbrev to UInt and PInt.
If the above 2 are parameterized, then just ditch them and people can use
IntBetween instead, which will let people have all of the above control,
plus more, and its radix independent.
]
SmallInt
BigInt
These above 2 are particularly bad; at least get rid of them if you don't
adopt any of my other suggestions. Instead, let people use IntBetween (or
a parameterized Signed/UnSigned) to specify what range of integers they
want to allow. Saying 'Small' or 'Big' means different things to everyone
and such things are better off being user-defined.
Str[
ASCII
Printable
Word (must be a single 'word')
No specific comments but the above 3 seem interesting; there should be
something more generic there, maybe Repertoire, eg:
Repertoire[ASCII]
Repertoire[IsoLatin1]
MaxLength
MinLength
EqualTo || 'eq'
About EqualTo, see my previous comment on Num's version.
]
ClassName[
PackageBase (For stuff like '::Plugin::MyPlugin')
]
Ref
ScalarRef
ArrayRef[`a][
MaxElements
MinElements
]
HashRef[`a][
HasAllKeys
]
CodeRef
RegexpRef
GlobRef
FileHandle
Object[
HasMethods
ISA
]
Role[
Requires
Does
]
-- Darren Duncan