更改自定义中缀操作以编译为其他内容

fre*_*ddy 5 raku

use Something;

sub infix:<%%%>(*@args) is assoc("list") { [*] @args }

say 9 %%% 10;
say 9 %%% 10 %%% -44; 
Run Code Online (Sandbox Code Playgroud)

我想更改它,以便编译为28 %%% 5第一个和28 %%% 5 %%% -22第二个,因为如果操作数是奇数,则它是 3*$_+1 。如果操作数是偶数,则减半。我应该做什么才能use Something使这项工作成功

rai*_*iph 5

TL;谜语博士。什么时候半个答案就已经是答案了?答案:当你什么都不做而加倍时。那不是东西吗?

最初的例子没有Something

sub infix:<%%%>(*@args) is assoc("list") { [*] @args }

say 9 %%% 10;         # 90
say 9 %%% 10 %%% -44; # -3960
Run Code Online (Sandbox Code Playgroud)

目标是引入Something上述 (90-3960) 的输出更改为下面 (140-3080) 的输出:

say 28 %%% 5;         # 140
say 28 %%% 5 %%% -22; # -3080
Run Code Online (Sandbox Code Playgroud)

从这里开始,我们不关心第二个示例,只需获取第一个示例的这两个数字输出。

第一次尝试某事。半个答案?

引入自定义中缀*并将oddeven其作为参数。将其放在文件顶部进行测试(稍后我们可以将其弹出到模块中):

# use Something;

sub oddeven ($_) { $_ %% 2 ?? $_/2 !! &CORE::infix:<*>(3,$_) + 1 }

sub infix:<*>(*@args) is assoc<right> { &CORE::infix:<*>( |@args>>.&oddeven ) }

# Your original code:

sub infix:<%%%>(*@args) is assoc("list") { [*] @args }

say 9 %%% 10;         # 140
say 9 %%% 10 %%% -44; # -1540
Run Code Online (Sandbox Code Playgroud)

-1540只是应有的一半。&oddeven显然在中间的参数上被评估了两次。唔。

一个答案?一半时间什么也不做。

介绍noop角色(特质)并适当使用:

role noop {}

multi oddeven (noop $_) { $_ }
multi oddeven (     $_) { $_ %% 2 ?? $_/2 !! &CORE::infix:<*>(3,$_) + 1 }

sub infix:<*>(*@args) is assoc<right> { &CORE::infix:<*>( |@args>>.&oddeven ) but noop }

sub infix:<%%%>(*@args) is assoc("list") { [*] @args }

say 9 %%% 10;         # 140
say 9 %%% 10 %%% -44; # -3080
Run Code Online (Sandbox Code Playgroud)
  • 声明一个noop不做任何事情的角色。

  • 分裂,oddeven对争论不采取任何行动noop

  • 将标签添加noop到由我的自定义中缀计算的值中*,这样oddeven当第二次调用该值时,就不会再影响它了,就像链式表达式中发生的情况(以 中开头的值10)一样9 %%% 10 %%% -22

我将把它放入模块中作为读者的练习。

问题解决了?

这取决于 X 的性质(大概是XY 问题)。我故意选择不去探索你真正想要的东西 ( X),而是专注于问题Y,即你字面意义上问的问题。

我已经想出了答案,但是,但是but…… 另外,我很累,所以我没有解释一些可能需要解释的代码。所以也许这还不是一个可以接受的答案。如果没有的话,我们谈谈吧,但不会是今晚。