Sobrecarga do operador Raku

8

Usando o seguinte código:

use v6d;

# sub circumfix:<α ω>( @a ) {
#     @a[0] >= @a[1] & @a[0] <= @a[2];
# };

sub circumfix:<α ω>( $a, $b, $c ) {
    $a >= $b & $a <= $c;
};

if (α <5 0 10> ω) {
    say 'Truthy';
}
else {
    say 'Falsey';
}

Resulta em:

(base) hsmyers@BigIron:~/board$ perl6 ./op.p6
Too few positionals passed; expected 3 arguments but got 1
  in sub circumfix:<α ω> at ./op.p6 line 7
  in block <unit> at ./op.p6 line 11

Enquanto a troca do bloco comentado pela outra definição resulta em:

(base) hsmyers@BigIron:~/board$ perl6 ./op.p6
Truthy

A versão quebrada (com três parâmetros) é a que eu quero, alguém poderia explicar por que está quebrada?

hsmyers
fonte

Respostas:

10

<5 0 10>literalmente constrói a List, um único List .

Uma analogia seria uma lista de coisas a fazer, uma lista de tarefas. Quantas coisas é uma lista de tarefas? É 1 - uma lista de tarefas.

Assim, você recebe a mensagem de erro:

expected 3 arguments but got 1

O que você deseja é especificar que deseja um valor que seja ele próprio composto por vários valores. Aqui está uma maneira de fazer isso:

sub circumfix:<α ω>( ( $a, $b, $c ) ) ...

O ambiente adicional (e )causa a desestruturação .

raiph
fonte
1
Uma alternativa poderia ser usar uma assinatura slurpy (*@foo where .elems == 3)que poderia então suportar α $a, $b, $c ωouα ($a, $b, $c) ω
user0721090601
@ user0721090601 Os sub-sigs também suportam. Colocar riqueza de assinatura em sub-sigs fornece ao compilador mais conhecimento do que uma wherecláusula, para que você obtenha, por exemplo, uma mensagem de erro padrão mais agradável e velocidade de envio. Acho as wherecláusulas melhores para condições arbitrárias que um sub-sig não pode manipular ou para definir uma mensagem de erro totalmente personalizada (por exemplo ( *@ where { .elems == 3 or die "nope" } )). Observe que você pode combinar estes: ( *@ where { .elems == 3 or die "nope" } ($a, $b, $c) )fornece a você a destruição em variáveis ​​nomeadas quando obtém o (s) argumento (s) correto (s) e uma mensagem de erro personalizada quando não obtém.
raiph
1
++ multi sigs funcionaria para evitar o where, mas eu não sabia que alguém poderia usar o anônimo para desestruturar enquanto fornecia um where (quero dizer, achei que você nunca poderia ver um exemplo e é realmente legível, na verdade)
user0721090601
Sim para multis, muito melhor do que minha sugestão de abusar de uma wherecláusula para um caso de uso de erro que possa ser distinguido por várias assinaturas sem wherecláusulas. (Em retrospecto, fico envergonhado com a revelação de meus instintos mais loucos, quando eles seriam tão desnecessários e inapropriados!) De qualquer forma, tenha outro voto positivo e obrigado por melhorar nossa resposta com seus comentários. :)
raiph
7
D:\>6e "say <5 0 10>"
(5 0 10)

Esses não são três argumentos. É uma lista de três valores (do tipo IntStr) e, portanto, um único argumento.

Holli
fonte