混合 Str 和 Int 参数的 perl6 最小值和最大值

perl6 min and max of mixed Str and Int arguments

当参数包含 Str 和 Int 的混合时,对于 min 和 max 例程首先转换什么类型?

To exit type 'exit' or '^D'
> say ("9", "10").max
9
> say ("9", "10").max.WHAT
(Str)
> say (9, "10").max
9
> say (9, "10").max.WHAT
(Int)                     # if convert to Int first, result should be 10
> say ("9", 10).max
9
> say ("9", 10).max.WHAT
(Str)                     # if convert to Str first, result should be 9
> say (9, "10").min
10
> say (9, "10").min.WHAT
(Str)                     # does min and max convert Str or Int differently?

如果 min 或 max 将参数转换为第一个参数的类型,这里的结果仍然不一致。

谢谢指教!!!

minmax 都使用 cmp 中缀运算符进行比较。如果类型不同,则使用此逻辑(稍微重写为纯 Perl 6,而真正的使用内部快捷方式):

multi sub infix:<cmp>($a, $b) {
    $a<> =:= $b<>
      ?? Same
      !! a.Stringy cmp b.Stringy
}

实际上,如果两个东西指向完全相同的对象,那么它们就是 Same,否则将两者都字符串化,然后进行比较。因此:

say 9 cmp 10;      # uses the (Int, Int) candidate, giving Less
say "9" cmp "10";  # uses the (Str, Str) candidate, giving More
say 9 cmp "10";    # delegates to "9" cmp "10", giving More
say "9" cmp 10;    # delegates to "9" cmp "10", giving More

转换为字符串是为了比较(作为 cmp 的实现细节),因此对 min 或 [= 返回的值没有影响13=],这将是在输入列表中找到的。

嗯,jnthn 已经回答了。他的回答总是权威的,而且通常也非常清晰和简洁。这个也不例外。 :) 但我已经开始了,所以我会完成并发布...

一个search for "method min" in the Rakudo sources yields 4 matches of which the most generic is a match in core/Any-iterable-methods.pm6.

它可能看起来很难理解,但实际上 nqp 本质上是 P6 的一个简单子集。关键是它使用 cmp 来比较从被比较的值序列中提取的每个值与最新的最小值($pulled cmp $min 位)。

接下来是 search for "sub infix:<cmp>" in the Rakudo sources。这会产生 14 个匹配项。

所有这些都必须查看以确认源代码显示的是什么来比较这些不同类型的值。另请注意,每一对的逻辑都是成对的,想想有点奇怪。因此,如果有三个值 abc,每个值都是不同的类型,那么逻辑将是 a 是初始最小值,然后会有是一个 b cmp a ,它将是 cmp 逻辑在该顺序中为该类型组合赢得的任何内容,然后 c cmp d 其中 d 是赢得 b cmp a 比较的任何一个并且 cmp 逻辑将是任何适合 that 类型对的顺序。

让我们从第一个开始 -- the match in core/Order.pm6 -- 如果其他匹配中的 none 更具体的话,这大概是一个包罗万象的:

  • 如果 cmpboth 个参数都是数字,那么比较是一个合适的数字比较(例如,如果它们都是 Ints 然后比较是两个任意精度整数)。

  • 如果一个参数是数字而不是另一个,那么-InfInf被排序到开始和结束但是否则,在两个参数都被 .Stringyfication.

  • 强制后进行比较
  • 否则,两个参数都被.Stringyfication强制转换。

所以,这是默认值。

下一个必须通过单独的重载。例如,下一个是 the cmp ops in core/allomorphs.pm6 并且我们看到对于同质类型(IntStr 等)如何比较首先是数字,然后是字符串,如果不能解决它的话。注意评论:

we define cmp ops for these allomorphic types as numeric first, then Str. If you want just one half of the cmp, you'll need to coerce the args

无论如何,我看到 jnthn 发布了另一个很好的答案,所以是时候结束这个了。 :)