Raku如何进行类别名的操作?

5

我有

class Length is Measure export { ... }

我希望有仅在类名不同的同义词,我已尝试过以下操作:

class Distance   is Length is export {}
class Breadth    is Length is export {}
class Width      is Length is export {}
class Height     is Length is export {}
class Depth      is Length is export {}

这种用法$distance ~~ Length是可以的,但我也希望$length ~~ Distance。

某种强制转换方式可能更可取 - 比如 $length.Distance ~~ Distance,以防止像$width = $height + $depth这样的操作(即不能总是将沿不同轴的长度相加)。

也许可以使用某种类似于:=名称绑定的方式,或者一种缩写方式来强制转换NxN?

非常感谢您提供的任何建议...

2个回答

6

这并不是一个完整的答案,但可能会成为一个。

以下标题对您是否有用?我不一定意味着您要使用组合而不是继承(role),直接别名(constant),混入(but),或动态类型约束(where)。下面的代码只是快速原型开发的一种方式,直到您提供反馈意见。

role Measurement {}
role Height does Measurement {}
role Width does Measurement {}
constant Breadth = Width;
say Width;                             # (Width)
say Breadth;                           # (Width)
say ::<Breadth>:kv;                    # (Breadth (Width))
say Breadth ~~ Width;                  # True
say Width ~~ Breadth;                  # True

multi infix:<+>
  (::L Measurement \l, 
       Measurement \r where * !~~ L)
{ fail }

say (42 but Width) + (99 but Breadth); # 141
say (42 but Width) + (99 but Height);  # Failed...

嗨@raiph - 实际上我已经将codesections标记为答案 - 但现在我已经改成了你的,因为它不需要深入挖掘ACCEPTS内省细节,并且我认为通过在更高的抽象层次上工作具有更清晰的表述。此外,它涵盖了我“提问”的两个部分。两个答案都很好!谢谢... - librasteve

4

我可能需要看到更多的使用情况才能百分之百确定最佳方法,但至少在确保所有长度方面

class A { 
  method ACCEPTS($other) { $other.isa: A }
}

class B is A { }
class C is A { }
class D is A { }

my $b = B.new;
my $c = C.new;
my $d = D.new;

say $b ~~ D; # True
say $d ~~ C; # True
say $c ~~ B; # True

因为在这里ACCEPTS是在A上定义的,所以将使用它来匹配B/C/D。默认情况下,ACCEPTS使用isa($?CLASS)进行智能匹配,这就是为什么它返回false的原因,但现在它将始终锁定使用A
另一种方法是将类设置为别名。通常,在您想要缩短从模块导入的较长类的名称时,这很有用,但在这里也可以使用:
class A { ... }
our \B = A;   my $b = B.new;
our \C = A;   my $c = C.new;
our \D = A;   my $d = D.new;

say $b ~~ A & C & D; # True

say $b.WHAT; # A
say $b.WHAT; # A
say $b.WHAT; # A

您会发现所有这些声明都声称是A,因为它们确实是。我们只是提供了另一种访问A的方式。这意味着不仅B通过DA的标准,而且它与它们相同,因为它与它们相同(存储在内存中的位置也相同),所以根本无法区分它们。


稍微扩展一下,你可能希望A(或者你问题中的Length)实际上是一个Role而不是一个Class,这取决于你想要创建的确切关系。 - codesections
嗨@codesections - 这正是我想要的--我认为ACCEPTS方法会做我想要的事情(如果我选择轻量级强制转换,我可能还可以弄清如何相应地调整ACCEPTS)。原则上,我同意您在角色组合性方面的观点,但是,我固执地认为长度是一种度量。;-) - librasteve
@p6steve ACCEPTS 是智能匹配背后的函数--您可能已经知道了。https://www.nntp.perl.org/group/perl.perl6.users/2019/12/msg7408.html - jubilatious1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接