Totally as an Ada-type-system learning exercise, I was trying to make 3 types (or rather, a type and 2 subtypes):
Month_Type
, an enumeration of all monthsShort_Month_Type
, a Month_Type
subtype only having the months with 30 daysFebruary_Month_Type
, a subtype with just FebruaryIt seems that subtypes must use the range
mechanism, correct? (Is there any other kind of subtype?) In order to get it to work with contiguous ranges, I had to put my Month_Type
enumeration in this order:
type Month_Type is (February, April, June, September, November, January, March, May, July, August, October, December);
Obviously this isn't the natural order of months, and I could see people/me trying to do Month_Type'First
or something expecting to get January.
So, two general questions from this silly example:
Thanks!
A subtype is a type together with a constraint; a value is said to belong to a subtype of a given type if it belongs to the type and satisfies the constraint; the given type is called the base type of the subtype.
The basic difference is that a derived type is a different type. You cannot just assign one to the other, or use them together in an expression. A subtype on the other hand is assignment-compatible with its original type. You use them together without having to enter any type-munging code.
You can make an object that designates only certain values in an enumeration. We would generally call this a "set".
A lot of languages have sets as basic types (along with arrays and records). Of course some don't. Ada is kind of in the middle. It doesn't offically have type named "set" or anything, but boolean operations are defined to work like bitwise logical operations on arrays of boolean
. If you pack the array, you get pretty much exactly what other languages' "set" type give you. So Ada does support sets, they are just called "arrays of boolean".
type Month_Set is array (Month) of Boolean;
Short_Month : constant Month_Set :=
(September => true, April => true, June => true, November => true,
February => true, others => false);
Y_Month : constant Month_Set :=
(January => true, February => true, May => True, July => true,
others => false);
-- Inclusion
if (Short_Month(X)) then ...
-- Intersection (Short_Y will include only February)
Short_Y := Short_Month and Month_Ending_in_Y;
-- Union (Short_Y will include All Short_Months and all Y_Months
Short_Y := Short_Month or Month_Ending_in_Y;
-- Negation (Short_Y will include all Short_Months not ending in Y
Shorty_Y := Short_Month and not Month_Ending_in_Y;
You can use subtype predicates. In your case:
subtype Short_Month_Type is Month_Type with
Static_Predicate => Short_Month_Type in April | June | September | November
No, an enumeration subtype only admits a range_constraint in this context, but you could create any number of Sets using Ada.Containers.Ordered_Sets
. There are examples here and here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With