Perl 6有无限的Int吗?

bri*_*foy 9 perl6

我有一个任务,我想找到最接近目标的字符串(因此,编辑距离),而不是同时生成它们.我想我会在初始化最近的编辑距离时使用高水位技术(低,我猜),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;
    }
Run Code Online (Sandbox Code Playgroud)

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

分配到$ nearest-so-far的类型检查失败; 预期Int但得到Num(Inf)

我可以制定约束Num并强制执行:

    state Num $closest-so-far = Inf;
    ...
        $closest-so-far = $string.chars.Num;
Run Code Online (Sandbox Code Playgroud)

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

有什么我想念的吗?我原以为任何数字的东西都可能有一个特殊的值,它比所有其他值更大(或更小).多态性和所有这些.

rai*_*iph 8

{新的介绍,希望比无益/误导的原版更好}

@CarlMäsak,在他的第一个版本之后,他在下面写了这个答案:

上次我和Larry讨论了这个问题{2014年},他的理由似乎是...... Inf应该适用于所有的Int,Num和Str

(我的回答的第一个版本开始于一个"回忆",我得出的结论至少是无益的,似乎是完全错误的记忆.)

在我对Carl的评论做出的研究中,我确实在2016年找到了#perl6-dev中的一个相关宝石,当时Larry写道:

那么我们的政策可能是,如果你想要一个支持±Inf和NaN的Int,请改用Rat

换句话说,不要让Rat与Int一致,使其与Num一致

拉里写了这篇文章6.c.喜欢讨论我不记得看到任何东西6.d.

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


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

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


我在下面提出的问题的解决方案是where通过a 使用一个子句subset.

一个where子句允许指定运行时分配/结合"typechecks".我引用"类型检查",因为它是最强大的检查形式 - 它在计算上是通用的,并且字面上检查实际的运行时值(而不是静态类型的视图,该值可以是什么).这意味着他们更慢和运行时,不编译时间,但它也使他们的方式更强大的(更不用说比较容易的方式来表达),甚至比依赖类型这是一个比较前沿的功能,那些谁是为先进静态类型检查语言倾向于声称只在他们自己的世界1中可用,并且旨在"通过允许非常富有表现力的类型来防止错误"(但是好好弄清楚如何表达它们......;)).

一个子集的声明可以包括一个where条款.这允许您命名检查并将其用作命名类型约束.

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

subset Int-or-Inf where Int:D | Inf;
Run Code Online (Sandbox Code Playgroud)

现在只需将其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
Run Code Online (Sandbox Code Playgroud)

1.请参阅Perl 6是否支持依赖类型?并且它似乎粗糙的共识是没有.