一般来说,我需要的是类型转换指令,例如能够像5 * true
那样对其进行乘法运算,并获得5
的{{1}}并得到x * false
。
怎么做这样的事情?
答案 0 :(得分:2)
你可以用:
subs([false=0, true=1], expr);
答案 1 :(得分: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
您还可以尝试使用模块导出(从而在交互式使用的“顶层”重新定义)增强型*
。
NB。下面这个导出过程*
的一个更仔细的版本只会替换'true'和'false',如果作为整个被乘数发生,并且不会在所有表达式中替换。 (标量表达式可以在其中包含未评估的函数调用,例如,“true”和“false”出现在可选参数中。理想情况下,这些应该保持不变。)
> 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时,不会调用新的*
。也许有可能解决这个问题,虽然结果显示不太好(并且解决方案可能会“打破”你可能想要的所有其他东西),
> 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)的对象实际上就未调整函数调用新*
而言。因此,当替换b = false时,会调用新的*
,并且可以获得所需的结果。 (希望在我忽略的情况下,这不会导致无限递归。)