cod*_*ons 5 pattern-matching compile-time raku
考虑以下玩具代码:
my $age-check = do given 18 {
when $_ > 18 { 'old enough' }
when $_ < 18 { 'too young' }
};
say "The user is $age-check" # OUTPUT: «The user is False»
Run Code Online (Sandbox Code Playgroud)
此代码包含导致运行时错误的错误(不处理输入正好为 18 的情况)。有没有办法通过要求given块完全匹配来在编译时捕获此错误?它看起来像有应该使用的方式CHECK移相器或类似的东西,要求匹配是详尽的,但我不能肯定我怎么会去这样做。
(我知道您可以在运行时通过抛出错误的情况更早地捕获default错误,但这不是我要问的问题。如果 Raku 没有办法在编译时强制执行详尽匹配,那也不是什么大缺点语言 - 但它可能是一个有用的功能。)
虽然您可以编写一个模块来强制执行这些内容(尤其是在 RakuAST 出现时),但它会处理给定的语句,这将非常棘手,并且实际上只能用于基本的数值运算。
given/的语义when基本上是
given $foo { # topicalize $foo
when $bar1 { … } # if $foo ~~ $bar1
when $bar2 { … } # elsif $foo ~~ $bar2
when $bar3 { … } # elsif $foo ~~ $bar3
default { … } # else
}
Run Code Online (Sandbox Code Playgroud)
如果您的条件是复杂的东西,例如.is-primeand * %% 2,甚至是不确定的(针对可变对象的智能匹配),则很难或不可能确定。
如果您想对某些条件子集强制执行此级别的严格行为,您可以执行类似于以下内容的解决方法:
sub is-exhaustive(@conditions) {
... # complex algorithm to determine that the conditions are exhaustive
}
my %foo =
less-than-eighteen => * < 18,
more-than-eighteen => * > 18,
exactly-eighteen => * == 18;
CHECK die unless is-exhaustive %foo.values;
given $bar {
when %foo<less-than-eighteen> { ... }
when %foo<more-than-eighteen> { ... }
when %foo<exactly-eighteen> { ... }
}
Run Code Online (Sandbox Code Playgroud)