Perl 6 是否有一个无限的 Int? [英] Does Perl 6 have an infinite Int?

查看:47
本文介绍了Perl 6 是否有一个无限的 Int?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I had a task where I wanted to find the closest string to a target (so, edit distance) without generating them all at the same time. I figured I'd use the high water mark technique (low, I guess) while initializing the closest edit distance to Inf so that any edit distance is closer:

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;
    }

但是,InfNum 所以我不能这样做:

However, Inf is a Num so I can't do that:

类型检查在赋值给 $closest-so-far 时失败;预期 Int 但得到 Num (Inf)

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

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

I could make the constraint a Num and coerce to that:

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

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

However, this seems quite unnatural. And, since Num and Int aren't related, I can't have a constraint like Int(Num). I only really care about this for the first value. It's easy to set that to something sufficiently high (such as the length of the longest string), but I wanted something more pure.

有什么我遗漏的吗?我原以为任何数量的事物都可能具有大于(或小于)所有其他值的特殊值.多态性等等.

Is there something I'm missing? I would have thought that any numbery thing could have a special value that was greater (or less than) all the other values. Polymorphism and all that.

推荐答案

{新的介绍,希望比没有帮助/误导的原始介绍更好}

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

@CarlMäsak, in a comment he wrote below this answer after my first version of it:

上次我在 2014 年与拉里谈过这件事{2014 年},他的理由似乎是... Inf 应该适用于所有 Int、Num 和 Str

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

(我的回答的第一个版本以回忆"开头,我得出的结论是至少没有帮助,而且可能是完全错误的记忆.)

(The first version of my answer began with a "recollection" that I've concluded was at least unhelpful and plausibly an entirely false memory.)

在我针对 Carl 评论的研究中,我确实在 #perl6-dev in 2016 当 Larry 写道:

In my research in response to Carl's comment, I did find one related gem in #perl6-dev in 2016 when Larry wrote:

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

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

换句话说,不要让Rat和Int一致,要和Num一致

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

Larry 写了这篇文章 6.c.我不记得看到过类似讨论 for 6.d.

Larry wrote this post 6.c. I don't recall seeing anything like it discussed for 6.d.

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

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

Num in P6 implements the IEEE 754 floating point number type. Per the IEEE spec this type must support several concrete values that are reserved to stand in for abstract concepts, including the concept of positive infinity. P6 binds the corresponding concrete value to the term Inf.

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

Given that this concrete value denoting infinity already existed, it became a language wide general purpose concrete value denoting infinity for cases that don't involve floating point numbers such as conveying infinity in string and list functions.

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

The solution to your problem that I propose below is to use a where clause via a subset.

where 子句 允许指定运行时分配/绑定类型检查".我引用类型检查"因为它是最强大的检查形式——它是计算通用 并逐字检查实际的运行时值(而不是该值的静态类型视图).这意味着它们更慢 和运行时,而不是编译时,但这也使它们方式依赖类型,这是一个相对前沿的特性,那些使用高级静态类型检查语言的人倾向于声称只在他们自己的世界中可用1 并且旨在通过允许极具表现力的类型来防止错误";(但祝你在弄清楚如何表达它们时好运......;)).

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 which are a relatively cutting edge feature that those who are into advanced statically type-checked languages tend to claim as only available in their own world1 and which are intended to "prevent bugs by allowing extremely expressive types" (but good luck with figuring out how to express them... ;)).

子集声明可以包含where 子句.这允许您命名检查并将其用作命名类型约束.

A subset declaration can include a where clause. This allows you to name the check and use it as a named type constraint.

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

So, you can use these two features to get what you want:

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

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

Now just use that subset as a type:

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.请参阅 Perl 6 是否支持依赖类型?似乎粗略的共识是否定的.

这篇关于Perl 6 是否有一个无限的 Int?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆