I have this;
multi sub infix:<+> ( Measure:D $left, Measure:D $right ) is equiv( &infix:<+> ) is export {
my ( $result, $argument ) = inf-prep( $left, $right );
return $result.add( $argument );
}
multi sub infix:<+> ( Measure:D $left, $right ) is equiv( &infix:<+> ) is export {
my ( $result, $argument ) = inf-prep( $left, $right );
return $result.add( $argument );
}
multi sub infix:<+> ( $left, Measure:D $right ) is equiv( &infix:<+> ) is export {
my ( $result, $argument ) = inf-prep( $left, $right );
return $result.add( $argument );
}
Is there a shorthand to avoid three multi sub declarations - the main aim here is to catch anything that has my custom Type i.e. Measure.
In your signature you can use a single Capture for all parameters and constraint them with a where
clause inspecting the capture for the desired number of positionals and if the Type is present.
For example the following sub expects two positionals where at least one is Int:D:
sub callWithInt(|c where { .elems == 2 && .list.any ~~ Int:D }) {
# Just show the first Int:D received
"called with {c.list.first(* ~~ Int)}".say
}
If you need to define different subs with the same signature, to avoid repeating the clause, create first a subset
and use it as constraint:
subset hasInt of Capture where {
.elems == 2 # Number of required positionals
&& .list.any ~~ Int:D # a Junction for the Type check
# Avoid LTA error messages
or fail('Need 2 positionals with an Int')
};
sub cwInts(hasInt |c) {
"called with {c.list.first(* ~~ Int)}".say
}
sub adder(hasInt |c) { … }
cwInts(1, 'bar'); # "called with 1"
cwInts('foo', 3); # "called with 3"
cwInts('foo', 'barr') # Error! "I need 2 positionals with an Int"
cwInts(8); # Error!
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