【问题标题】:How is this Perl sensical, considering Perl 6's type system?考虑到 Perl 6 的类型系统,这个 Perl 的意义如何?
【发布时间】:2016-01-25 16:39:35
【问题描述】:

我打算把它编辑成my other related question,但感觉已经很不一样了,我不想每个问题都问太多问题。


我的心……已经爆炸了。

考虑:

use strict;

my Int $n = 6;
my Str $x = "a";
my @l = $n, $x;
say @l ~~ List;

按预期打印True

考虑一下:

use strict;

my Int $n = 6;
my Str $x = "a";
my List @l = $n, $x; # <-- only change is the type notation
say @l ~~ List;

死于:

Type check failed in assignment to @l; expected List but got Int

所以... List 的类型是 List,但我不能它是 List,因为那是一种罪过!

这里发生了什么?这是一个错误吗?还是我将我不相关的 Python 和 Go 习语带到 Perl 并破坏了一些东西?

【问题讨论】:

  • @Hunter,你让漂亮的颜色消失了! (我用perl 标记它的原因是我可以突出显示语法,但如果你认为组织更重要,那么就足够公平了。)
  • 显然 perl6 标签没有与之关联的默认语法高亮提示。我现在已经添加了 Perl 5 提示。我没有使用过 Perl 6,但我猜测语法足够接近,突出显示应该是相同的。也许我会在 Meta 上提出请求。
  • @ThisSuitIsBlackNot 实际上有很多新语法。根据我的经验,有时即使 vim 也很难处理。
  • @ChristopherBottoms 很高兴知道。差异是否足够明显,以至于 SO 上的突出显示始终是坏/错误? Google prettify 非常简单,有时会搞砸 Perl 5 的高亮显示,但对于大多数问题来说都很好,而且通常总比没有高亮显示要好。
  • @ThisSuitIsBlackNot 我认为 Meta 上的帖子是获得反馈的好主意,例如,我认为分离对于组织和让“正确”的人来查看问题都是有益的。对 Perl5 的了解并不意味着对 Perl6 有任何了解。如果用户对两种语言都感兴趣,可以同时订阅这两种语言。

标签: types raku


【解决方案1】:
my List @l = $n, $x;

没有做你认为它做的事。它没有声明@lList。它声明@l 的元素将是Lists。您无需声明 @l 将是一个数组;你在使用印记时已经这样做了。

您可以通过将List 替换为Int 来移动爆炸,以使Perl 6 期望Ints 的列表。

【讨论】:

  • @cat 你可以强制它成为 Positional 的特定类 my class MyArray does Positional {...}; my @a is MyArray; 这对于哈希的某些用途很有用 my %h is SetHash; %h{$_}++ for 'HelloWorld'.comb; say %h => SetHash.new(r, l, W, H, e, d, o)␤ 你目前不能将此语法与赋值结合使用虽然这使得my @a is List; 变得毫无意义,因为你永远不能为它分配任何元素(默认是可变的数组)。
  • @BradGilbert:但你可以使用绑定; my @a is List 变量不能绑定到不是从 List 派生的东西
  • @Christoph 我以为我在声明后尝试了绑定,但我想我没有。
【解决方案2】:
my List @l;

的简写符号
my @l is Array of List;

在数组的元素上放置List类型约束。

容器上的类型约束已经通过@ sigil 表示,对应于角色Positional,而% sigil 对应于角色Associative

$ 变量的情况类似,因为还涉及一个容器(Scalar),其单个元素受到约束。但是,该约束还允许直接重新绑定到去容器化的值1


1 如果以上对您没有意义,您应该查看赋值= 和绑定:= 之间的区别。通过.VAR.WHAT 检查变量也可能具有指导意义。

请注意,我们也可以重新绑定到另一个标量容器,只要它的 元素 在绑定时满足类型约束。

这可以用来颠覆类型系统:

my Int $a;
my $b = 42;
$a := $b;
$b = "not cool";
say $a;

不酷:(

【讨论】:

  • 这种类型系统的作弊是故意允许的吗?
  • @cat:对我来说看起来像一个错误(或者至少是一个错误);我想不出有什么明显的东西可以阻止解决这个问题
  • 这不是错误。 my Int $a 创建一个 Int 类型的标量容器,默认为 Int(没有名称),并将本地范围名称 $a 绑定到它。使用my $b = 42,您可以创建一个类型为 Any 且默认为 Any 的容器,并为其分配 42。 $a$b 的绑定将$a 的容器更改为$b 的容器。 $a 绑定的原始容器丢失。现在$a 的容器是Any 类型和默认Any。如果类型约束会坚持 name $a,那么您将永远无法将任何东西绑定到任何东西。
  • @gfldex:我很确定我有一个测试用例,其中约束在重新绑定后仍然存在(可能是由于一些静态分析?),但我无法重现它;我会看看我是否能弄清楚我之前做了什么......
  • @gfldex:我可能弄错了;但是,仍然存在的是对重新绑定变量的约束,例如my Int $a; my $b = 42; $a := $b; $a := Str
猜你喜欢
  • 1970-01-01
  • 2019-08-18
  • 1970-01-01
  • 2021-11-25
  • 2018-08-03
  • 2014-10-26
  • 1970-01-01
  • 1970-01-01
  • 2018-10-28
相关资源
最近更新 更多