如何用Perl 6的Junction复现Perl中List::Util::all的行为?
为啥你的Perl 6 Junction写法没生效?
嘿,这个问题我当初刚摸Perl 6 Junctions的时候也踩过同款坑!咱们先拆解清楚问题出在哪,再给你正儿八经的解决办法。
问题根源:Junctions是值聚合,不是自动函数映射
你写的这条语句:
return not know(@possible-dates) and not know tell day all(@possible-dates);
核心错误在于:all(@possible-dates)是把整个日期列表打包成了一个all类型的Junction值,然后直接传给了tell day函数。除非tell day特意做了Junction参数的处理(比如用多重派发),否则它根本不会自动遍历Junction里的每个日期去执行逻辑——这和你循环里**逐个调用tell day**的逻辑完全不是一回事!
而你的循环写法是显式地对每个日期单独执行tell day,再一步步积累逻辑与的结果,这才是你真正想要的「所有日期都满足not know tell day $date」的逻辑。
正确的Junction写法
要让Junction实现和循环完全等价的逻辑,你需要先把not know tell day $_这个判断逻辑映射到每个日期上,再把所有结果打包成all Junction。代码应该是这样的:
return not know(@possible-dates) && all( @possible-dates.map: { not know tell day $_ } );
嫌写map麻烦?还能用上Perl 6的点操作符(自动分发到列表每个元素)简化:
return not know(@possible-dates) && all( @possible-dates».&( -> $d { not know tell day $d } ) );
这段代码的逻辑和你的循环完全对齐:
- 先判断
not know(@possible-dates)是否为真 - 再检查所有日期对应的
not know tell day $date是否都为真 - 只有两者同时满足才返回True
额外小提示:Junction的短路特性
Perl 6的all Junction会在遇到第一个False值时就停止求值(和&&的短路逻辑一致),所以性能上和你的循环写法几乎没差别,不用担心效率问题。
内容的提问来源于stack exchange,提问作者Hunter McMillen
相关产品推荐
相关产品推荐

