Perl6:比较运算符~~

Igo*_*bin 14 operators perl6 raku

我不明白这种行为:

> sort([1,2,3,4]) ~~ sort([1,2,3,4])
False
Run Code Online (Sandbox Code Playgroud)

你能解释一下吗?根据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
> 
Run Code Online (Sandbox Code Playgroud)

从#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?»
Run Code Online (Sandbox Code Playgroud)

返回True(第1行)和False(第2行)的版本.

mor*_*itz 14

关键的观察是,sort实际上并没有返回一个列表:

> sort([1,2,3,4]).^name
Seq
Run Code Online (Sandbox Code Playgroud)

排序文档似乎已经过时了:(.我会尽快解决这个问题.

所以,Seq是一个序列,基本上是一个迭代器,你也可以像列表一样使用它.

但是,在默认模式下,当你迭代a时Seq,它不存储旧元素,主要是为了启用代码

for $filehandle.lines -> $line {
    # do something with $line here
}
Run Code Online (Sandbox Code Playgroud)

不泄漏记忆.(这与python的迭代器相当.)

所以,这可能就是为什么没有人实现Seq.ACCEPTS(智能匹配运算符~~调用ACCEPTS正确的参数)的行为就像你在这种情况下所期望的那样,因为这可能是一个破坏性的操作.因此默认ACCEPTS行为启动,进行身份比较,然后返回False.

如果您将代码更改为

> sort([1,2,3,4]) ~~ sort([1,2,3,4]).list
True
Run Code Online (Sandbox Code Playgroud)

它表现得像你想要的那样.

我将与其他Perl 6开发人员讨论是否Seq.ACCEPTS可以更改为更明智的行为.

  • 文档更新于https://github.com/perl6/doc/commit/f74384849d754ed550cfe335a332546be19770ec (5认同)
  • @IgorChubin"你只是不能确定是什么~~回归"哎哟.莫里茨对`.list`的建议是"排序"的结果可能是一个合适的工作.但是,仍然,哎哟.我不知道博客文章或任何解释P6如何改变语言的内容; 和烤; 和Rakudo.也许有人会写一个也解释2017.01的这个方面是如何构思,考虑和应用的; 改变是对的; 哪里错了; 等等 (3认同)
  • 谢谢你的回答.有趣,但这取决于实施:请参阅我的更新.所以你只是无法确定~~的回报 (2认同)

rai*_*iph 7

你写的文字是Arrays:

say WHAT [1,2,3,4] ; # (Array)
Run Code Online (Sandbox Code Playgroud)

平原Array被热切地评估,因此它们的内容始终是已知的.因此,当应用于具有相同类型和内容的s 时,~~运算符会产生:TrueArray

say [1,2,3,4] ~~ [1,2,3,4] ; # True
Run Code Online (Sandbox Code Playgroud)

但是你正在应用一个函数,所以你必须注意函数返回的内容.

sort函数返回一个Seq序列,这是一个根本不同的类型.

Seqs被懒惰地评估,所以它们的内容是未知的,直到它们被完全迭代,耗尽它们.通过两个Seqs看看它们是否相同是没有意义的,因为那时它们会筋疲力尽.

所以两个Seq元素的结构相同,它们本身并不相同:

say Seq.new([1,2,3,4].iterator) ~~ Seq.new([1,2,3,4].iterator) ; # False
Run Code Online (Sandbox Code Playgroud)

  • @raiph请不要删除你的答案. (3认同)