枚举如何扩充?

How are enums augmentable?

在 Raku 中,HOW 必须通过 archetypes 方法公开 archetypes 的列表,该方法用于确定类型实现的更广泛的特征,例如参数化或可组合性。我注意到 Metamodel::EnumHOW(与枚举一起使用的 HOW)具有 augmentable 原型,当 MONKEY-TYPING pragma 时,它被赋予可以在使用 augment 关键字组合后扩展的类型已启用。

我对为什么枚举可以扩充的第一个猜测是允许添加枚举值,所以我试着写这个:

use v6;
use MONKEY-TYPING;

enum Foo <foo bar baz>;
augment enum Foo <qux>;
say qux;

但这抛出:

bastille% raku test.raku
===SORRY!=== Error while compiling /home/morfent/test.raku
Redeclaration of symbol 'Foo'.
at /home/morfent/test.raku:5
------> augment enum Foo⏏ <qux>;

所以它们可能不打算以这种方式增强。

我的下一个猜测是,它们旨在针对枚举值进行扩充,而不是枚举类型本身。 augment,有趣的是,当你告诉它你正在扩充哪种类型时,它并没有考虑到一个类型实际上有什么,所以我尝试像扩充一个枚举一样 class:

use v6;
use MONKEY-TYPING;

enum Foo <foo bar baz>;

augment class Foo {
    proto method is-foo(::?CLASS:D: --> Bool:D) {*}
    multi method is-foo(foo: --> True)          { }
    multi method is-foo(::?CLASS:D: --> False)  { }
}

say foo.is-foo;

哪个有效:

bastille% raku test.raku
True

但这并不像你打算给我增加枚举的方式。 augment 的这种用法相当奇怪,并且没有任何暗示应该可以从其文档中做到这一点。您打算如何扩充枚举?

常见问题

is-foo 在使用签名和参数的特性方面相当笨拙。这取决于以下内容:

由于 foo 是比 ::?CLASS:DFoo:D 的别名)更具体的类型,因此在 foo 上调用此方法时,foo multi 将被选中并且 True 将被 returned,但在任何其他情况下,::?CLASS:D multi 将被选中并且 False 将被 returned。

在 Java 中,您几乎可以向枚举添加任意属性和函数。所以我确实认为以你描述的方式进行扩充是有道理的。例如:

use MONKEY-TYPING;

enum Days(Monday => 1, Tuesday => 2, Wednesday => 3, Thursday => 4, Friday => 5, Saturday => 6, Sunday => 7); 

augment class Days {
    proto method is-weekend(::?CLASS:D: --> Bool:D) {*} 
    multi method is-weekend(Saturday: --> True)          { } 
    multi method is-weekend(Sunday: --> True) {}
    multi method is-weekend(::?CLASS:D: --> False)  { } 

    proto method days-til-weekend(::?CLASS:D: --> Int:D) {*}
    # there is probably a better way to express this, but
    # hopefully the concept is clear
    multi method days-til-weekend(Monday: --> 4) {}
    ...
}

say Monday.is-weekend;
say Wednesday.days-til-weekend;
say Saturday.is-weekend;