4

一般来说,我需要的是类型转换指令,以便能够例如乘以 true like 5 * true和 get5的 sayx * false和 get 0

怎么做这样的事情?

4

2 回答 2

3

你可以这样做:

subs([false=0, true=1], expr);
于 2010-11-02T05:33:23.700 回答
2

有几种方法可以获得这种效果,您选择哪种方法可能取决于您打算用它做什么的更多细节。

最简单的是使用 2 参数eval(或subs,因为由于涉及精确 1 或 0 的产品的自动简化,应该进行评估)。

> eval( 5*true, [true=1,false=0]);
                           5
> eval( x*false, [true=1,false=0]);
                           0

当然,您可以创建一个程序来处理该评估,

> T := expr -> eval(expr,[true=1,false=0]):

> T( 5*true );
                           5
> T( x*false );
                           0

您还可以尝试使用模块来导出(并因此在交互使用的“顶级”重新定义)增强的*.

注意。下面这个导出过程的一个更仔细的版本*只会在作为整个被乘数出现时替换“真”和“假”,而不是在整个表达式中进行替换。(标量表达式中可以有未计算的函数调用,例如,可选参数中出现“真”和“假”。理想情况下,应该不理会这些。)

> M:=module() option package; export `*`;
>  `*`:=proc(ee::seq(anything))
>         :-`*`(op(eval([ee],[true=1,false=0])));
>       end proc;
> end module:

> with(M):

> 5*true;
                           5
> x*false;
                           0

> a*b*c;
                         a b c

> eval( %, b=false ); # this doesn't play along
                       a false c

请注意,在最后一个结果中,“false”的替换如何没有产生 0。这是因为 a*b*c(对于未知的 a、b 和 c)的结果是根据全局 :-*而不是新的*。因此,当 b=false 被替换时,不会调用 new *。也有可能解决这个问题,尽管结果显示不是那么好(并且解决方法可能会“破坏”你可能想要的其他东西),

> M:=module() option package; export `*`;
>   `*`:=proc(ee::seq(anything))
>          local res;
>          res:=:-`*`(op(eval([ee],[true=1,false=0])));
>          if type(res,:-`*`) then
>            'procname'(op(res));
>          else
>            res;
>          end if;
>        end proc;
> end module:

> with(M):

> 5*true;
                           5
> x*false;
                           0

> a*b*c;
                     `*`(`*`(a, b), c)

> eval( %, b=false );
                           0

在上面的最后一个示例中,看起来像*( *(a, b), c) 的对象实际上是根据对 new 的未评估函数调用*。因此,当 b=false 被替换时,就会调用 new*并且可以获得所需的结果。(希望在我忽略的情况下这不会导致无限递归。)

于 2010-11-03T05:36:18.980 回答