我不明白这种行为:
> sort([1,2,3,4]) ~~ sort([1,2,3,4])
False
你可以向我解释一下吗?
根据Perl 6,为什么这两个列表(显然相等)不相等。
更新
有趣,但它取决于Perl6版本(我刚刚注意到它):
$ which perl6
/usr/bin/perl6
$ dpkg -S `which perl6`
rakudo: /usr/bin/perl6
$ perl6 --version
This is perl6 version 2015.11 built on MoarVM version 2015.11
$ perl6
> sort([1,2,3]) ~~ sort([1,2,3])
True
>
$ export PATH=~/.rakudobrew/bin:$PATH
$ perl6 --version
This is Rakudo version 2017.12 built on MoarVM version 2017.12.1
implementing Perl 6.c.
$ perl6
To exit type 'exit' or '^D'
> sort([1,2,3]) ~~ sort([1,2,3])
False
>
关于#perl6的讨论:
[19:35] <+committable6> AlexDaniel,
¦2015.12,2016.01.1,2016.02,2016.03,2016.04,2016.05,2016.06,2016.07.1,2016.08.1,2016.09,2016.10,2016.11,2016.12: «True»
¦2017.01,2017.02,2017.03,2017.04.3,2017.05,2017.06,2017.07,2017.08,2017.09,2017.10,2017.11,2017.12,2018.01,HEAD(8afd791): «False»
返回True(第1行)和False(第2行)的版本。
答案 0 :(得分:14)
关键的观察是sort
实际上并没有返回一个列表:
> sort([1,2,3,4]).^name
Seq
documentation for sort似乎已过时了:(。我会尽快解决这个问题。
所以,Seq是一个序列,基本上是一个迭代器,你也可以像列表一样使用它。
但是,在默认模式下,当您迭代Seq
时,它不存储旧元素,主要是为了启用代码,如
for $filehandle.lines -> $line {
# do something with $line here
}
不泄漏记忆。 (这与python的迭代器相当。)
所以,这可能就是为什么没有人实现Seq.ACCEPTS
(智能匹配运算符~~
在正确参数上调用ACCEPTS
)的行为,就像你在这种情况下所期望的那样,因为这可能是破坏性的操作。因此,默认的ACCEPTS
行为会启动,进行身份比较,然后返回False
。
如果您将代码更改为
> sort([1,2,3,4]) ~~ sort([1,2,3,4]).list
True
它的行为与你想要的一样。
我将与其他Perl 6开发人员讨论是否可以将Seq.ACCEPTS
更改为更明智的行为。
答案 1 :(得分:7)
您撰写的文字是Array
s:
say WHAT [1,2,3,4] ; # (Array)
普通Array
被热切评估,所以他们的内容始终是已知的。因此~~
运算符在应用于具有相同类型和内容的True
时会产生Array
:
say [1,2,3,4] ~~ [1,2,3,4] ; # True
但是你正在应用一个函数,所以你必须注意该函数返回的内容。
sort
function会返回一个Seq
,一个序列,这是一种根本不同的类型。
Seq
被懒惰地评估,所以它们的内容是未知的,直到它们被完全迭代,耗尽它们。通过两个Seq
来查看它们是否等效是没有意义的,因为它们会耗尽。
因此,两个Seq
的元素结果相同并不相同:
say Seq.new([1,2,3,4].iterator) ~~ Seq.new([1,2,3,4].iterator) ; # False