我有一个任务,我希望找到最接近目标的字符串(因此,编辑距离),而不是同时生成所有字符串。我想我在使用高水位技术(低,我猜)时会将最近的编辑距离初始化为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所以我不能这样做:
类型检查失败,分配给$ nearest-so-far;预期Int但得到Num(Inf)
我可以将约束设为Num
并强制执行:
state Num $closest-so-far = Inf;
...
$closest-so-far = $string.chars.Num;
但是,这似乎很不自然。而且,由于Num
和Int
不相关,因此我不能拥有Int(Num)
之类的约束。我只关心这个第一个价值。很容易将其设置为足够高的东西(例如最长字符串的长度),但我想要更纯净的东西。
有什么我想念的吗?我原以为任何数字的东西都可能有一个特殊的值,它比所有其他值更大(或更小)。多态性和所有这些。
答案 0 :(得分:8)
{新的介绍,希望比无益/误导的原创介绍更好}
@CarlMäsak,在a comment he wrote below this answer我的第一个版本之后:
上一次I talked to Larry about this {in 2014},他的理由似乎是...... Inf应该适用于所有的Int,Num和Str
(我的回答的第一个版本以“回忆”开头,我得出的结论至少是无益的,似乎是完全错误的记忆。)
在我回应卡尔评论的研究中,当拉里写道时,我确实在#perl6-dev in 2016找到了一个相关的宝石:
那么我们的政策可能是,如果你想要一个支持±Inf和NaN的Int,请改用鼠标
换句话说,不要让Rat与Int一致,使其与Num一致
拉里写了这篇文章6.c
。我不记得看过像for 6.d
这样的讨论。
{现在回到我的第一个回答的剩余部分}
P6中的 Num
实现了IEEE 754浮点数类型。根据IEEE规范,此类型必须支持保留用于抽象概念的几个具体值,包括正无穷大的概念。 P6将相应的具体值绑定到术语Inf
。
鉴于这个表示无穷大的具体值已经存在,它成为一个语言范围的通用具体值,表示不涉及浮点数的情况的无穷大,例如在字符串和列表函数中传达无穷大
我在下面提出的问题解决方案是通过where
使用subset
子句。
where
clause允许指定运行时分配/绑定“typechecks”。我引用“typecheck”,因为它是最强大的检查形式 - 它是 computationally universal 并逐字检查实际的运行时值(而不是静态输入该值的类型视图)。这意味着它们是slower和运行时,而不是编译时,但它也使它们方式更强大(更不用说表达方式)甚至比{{3}那些进入高级静态类型检查语言的人倾向于声称只在他们自己的世界 1 中可用,并且旨在通过允许极具表现力的类型来防止错误“(但是好好弄清楚如何表达它们......;)。)。
dependent types可以包含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 。请参阅subset declaration和Does Perl 6 support dependent types?。