Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a shorthand where One <or> More positionals match a Type in a multi signature

Tags:

raku

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.

like image 423
p6steve Avatar asked May 30 '18 18:05

p6steve


1 Answers

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!
like image 140
Sortiz Avatar answered Nov 07 '22 07:11

Sortiz