For simple cases you can already use a union. For example, if you want to accept an Int, followed by either an ArrayRef or HashRef, you can do:
state $check = compile(Int, HashRef|ArrayRef);
However, this has limitations. For example, say we write a function that accepts either Int-then-ArrayRef or Str-then-HashRef; the obvious way is:
sub get_from {
state $check = compile(Int|Str, ArrayRef|HashRef);
my ($needle, $haystack) = $check->(@_);
is_HashRef($haystack) ? $haystack->{$needle} :
is_ArrayRef($haystack) ? $haystack->[$needle] :
die;
}
So we can do:
get_from(0, \@arr); # get index 0 from array
get_from('foo', \%h); # get key 'foo' from hash
which works, but is a looser check than we wanted - it will accept:
get_from('foo', \@arr); # !!!
It may be possible to do something like:
my $first_alt = Tuple[Int, ArrayRef];
my $second_alt = Tuple[Str, HashRef];
state $check = compile slurpy($first_alt|$second_alt);
Not sure how well making a union type slurpy works in practice. I think it ought to work in this particular case.
multisig() is more generic. You can just give each alternative whole signature as an arrayref:
state $check = multisig(
[ Int, ArrayRef ],
[ Str, HashRef ],
);
Although not yet documented, it's also possible to provide coderefs as alternatives. Let's say that we wanted to accept a third alternative where the first parameter is a method name and the second parameter is an object has that method:
sub get_from {
state $check = multisig(
[ Int, ArrayRef ],
[ Str, HashRef ],
sub {
my ($meth, $obj);
die unless is_Object($obj);
die unless $obj->can($meth);
return ($meth, $obj);
},
);
my ($needle, $haystack) = $check->(@_);
is_HashRef($haystack) ? $haystack->{$needle} :
is_ArrayRef($haystack) ? $haystack->[$needle] :
is_Object($haystack) ? $haystack->$needle :
die;
}
That all having been said, Type::Params is not the be all and end all of parameter processing. It's supposed to handle most common situations, but it's not always going to be enough.
When it's not, hopefully Type::Tiny can still help out with manual parameter processing. (Using check/assert/coerce methods.)
See also
https://metacpan.org/module/Type::Tiny::Manual::Params