Perl 6 有无限 Int 吗?

Does Perl 6 have an infinite Int?

我有一个任务,我想找到最接近目标的字符串(因此,编辑距离)而不是同时生成它们。我想我会使用高水位线技术(我猜是低),同时将最近的编辑距离初始化为 Inf 以便任何编辑距离更近:

use Text::Levenshtein;

my @strings = < Amelia Fred Barney Gilligan >;

for @strings {
    put "$_ is closest so far: { longest( 'Camelia', $_ ) }";
    }

sub longest ( Str:D $target, Str:D $string ) {
    state Int $closest-so-far = Inf;
    state Str:D $closest-string = '';

    if distance( $target, $string ) < $closest-so-far {
        $closest-so-far = $string.chars;
        $closest-string = $string;
        return True;
        }

    return False;
    }

但是,Inf 是一个 Num,所以我不能这样做:

Type check failed in assignment to $closest-so-far; expected Int but got Num (Inf)

我可以将约束设为 Num 并强制执行:

    state Num $closest-so-far = Inf;
    ...
        $closest-so-far = $string.chars.Num;

然而,这似乎很不自然。而且,由于 NumInt 不相关,我不能有像 Int(Num) 这样的约束。我只关心第一个值。很容易将其设置为足够高的值(例如最长字符串的长度),但我想要更纯粹的值。

有什么我想念的吗?我原以为任何数字都可以有一个特殊的值,它大于(或小于)所有其他值。多态性等等。

{希望比 unhelpful/misleading 原来的更好的新介绍}

@CarlMäsak,在 我的第一个版本之后:

Last time I talked to Larry about this {in 2014}, his rationale seemed to be that ... Inf should work for all of Int, Num and Str

(我的回答的第一个版本以一段“回忆”开始,我得出的结论是至少没有帮助,而且似乎完全是错误的回忆。)

在我回应 Carl 的评论的研究中,我确实在 #perl6-dev in 2016 中找到了一个相关的 gem,当时 Larry 写道:

then our policy could be, if you want an Int that supports ±Inf and NaN, use Rat instead

in other words, don't make Rat consistent with Int, make it consistent with Num

Larry 写了这个 post 6.c。我不记得看到过类似的讨论 for 6.d

{现在回到我第一个答案的其余部分}


P6中的

Num实现了IEEE 754浮点数类型。根据 IEEE 规范,此类型 必须 支持几个保留用于代表抽象概念的具体值,包括正无穷大的概念。 P6 将相应的具体值绑定到术语 Inf.

鉴于这个表示无穷大的具体值已经存在,它成为一种语言范围通用表示无穷大的具体值用于不涉及浮点数的情况,例如传递无穷大在字符串和列表函数中。


我在下面提出的解决问题的方法是通过 subset.

使用 where 子句

A where clause allows one to specify run-time assignment/binding "typechecks". I quote "typecheck" because it's the most powerful form of check possible -- it's computationally universal and literally checks the actual run-time value (rather than a statically typed view of what that value can be). This means they're slower and run-time, not compile-time, but it also makes them way more powerful (not to mention way easier to express) than even dependent types 这是一个相对前沿的功能,那些使用高级静态类型检查语言的人往往声称只有在他们自己的世界中可用1并且旨在“通过允许极富表现力的类型来防止错误”(但祝你好运弄清楚如何表达它们......;))。

一个subset declaration可以包含一个where子句。这允许您命名检查并将其用作命名类型约束。

因此,您可以使用这两个功能来获得您想要的:

subset Int-or-Inf where Int:D | Inf;

现在只需使用 subset 作为类型:

my Int-or-Inf $foo; # ($foo contains `Int-or-Inf` type object) 
$foo = 99999999999; # works
$foo = Inf;         # works
$foo = Int-or-Inf;  # works
$foo = Int;         # typecheck failure
$foo = 'a';         # typecheck failure

1。参见 Does Perl 6 support dependent types? and it seems the rough consensus is no