是否有一个简写,其中一个或多个位置匹配多个签名中的类型

时间:2018-05-30 18:08:37

标签: perl6

我有这个;

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 );
}

是否有速记来避免三个多子声明 - 这里的主要目的是捕捉任何具有我自定义类型的内容,即测量。

1 个答案:

答案 0 :(得分:1)

在您的签名中,您可以对所有参数使用单个 Capture,并使用 where 子句对其进行约束,以检查所需数量的位置的捕获以及是否存在类型。

例如,下面的 sub 需要两个位置,其中至少一个是 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
}

如果需要用相同的签名定义不同的子句,为避免重复子句,首先创建一个subset并将其用作约束:

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!