tobyink/p5-type-tiny

feature request - support + on Dicts / Enum

happy-barney opened this issue · 6 comments

Example:

declare Foo, as Dict[ foo => Int ];
declare Bar, as Dict[ bar => Int ];

declare FooBar, as Foo + Bar;
declare FooBar2, as Foo + Optional[Bar];

The | operator will kind of do this for enum already:

my $WarmColour = Enum[qw( red orange yellow )];
my $CoolColour = Enum[qw( green blue purple )];

my $Rainbow = $WarmColour | $CoolColour;

However, $Rainbow will be a Type::Tiny::Union instead of a Type::Tiny::Enum. (I might change that.)

The functionality seems somewhat useful for Dict, but given that it's just two or three types that it would be useful for, I don't think making it an operator overload is a good idea. Better a utility function:

declare FooBar, as Type::Util::combine_dicts( Foo, Bar );

you can also overload that operator only Dict class

use overload '+' => \&Type::Util::combine_dicts

here I'm inspired by typescript (there they use operator &) - maybe also some typescript type utilities (https://www.typescriptlang.org/docs/handbook/utility-types.html) may be useful (though also only for Dict)

Dict doesn't currently have its own class.

I know ... doesn't it deserve one? (just for these operators)
Another possible use-case - ^ for mutually exclusive fields

Foo as Dict[foo => Int];
Bar as Dict[bar => Int];

MyType = Foo ^ Bar + Dict[common => Int];

I've split this into two issues; one dealing with unions of enums, which I think can be dealt with quickly, and one dealing with combining Dicts, which has a number of open questions and will take longer to figure out.

FYI, in the latest dev release, Enum1 | Enum2 will combine two enums into a new enum.

(In older versions, it combines two enums into a Type::Tiny::Union, which has a similar effect, but means you don't get enum-specific methods on the result.)