Perl6是否支持依赖类型?

hao*_*rez 13 types perl6 dependent-type raku

我最近在维基百科页面查看依赖类型,我很想知道; Perl 6实际上是否引入了依赖类型?我似乎找不到可靠的消息来源.

这对某些人来说可能是显而易见的,但对我来说这肯定不明显.

rai*_*iph 12

反对 Ven,在Perl 6回答SO问题后的评论中"是否存在具有可约束类型的语言?",写道"perl6没有依赖类型",后来写了"依赖类型,可能不是,......好吧,如果我们得到可判定where的......"在#perl6的交换中.(拉里沃尔的回答是"朋友之间的一些停顿问题".顺便说一下,到目前为止,获得关于Perl 6所有事情的权威答案的最好方法是通过#perl6向TimToady提问.)

对于"依赖类型"SO标记的摘要是"依赖类型是依赖于值的类型".Perl 6支持依赖于值的类型,所以就是这样.

对于 Awwaiid更改的编辑摘要,将Perl 6添加到依赖类型的维基百科页面上说"Perl 6 ...具有不可判定的依赖类型".

维基百科页面以:

依赖类型是一种类型,其定义取决于值."整数对"是一种类型."第二个大于第一个的整数对"是依赖类型,因为它依赖于值.

这是在Perl 6中沿着这些行创建类型的一种方法:

subset LessMorePair of Pair where { $_.key < $_.value }
subset MoreLessPair of Pair where { $_.key > $_.value }

multi sub foo (        Pair) { "  P" }
multi sub foo (LessMorePair) { "LMP" }
multi sub foo (MoreLessPair) { "MLP" }

for 1 => 1, 1 => 2, 2 => 1 { say foo $_ }

#   P
# LMP
# MLP
Run Code Online (Sandbox Code Playgroud)

这是否意味着Perl 6 subset功能会生成依赖类型?也许这就是Awwaiid所想的.


Chr*_*oph 11

可以说是因为子集是可能依赖于任意条件的类型.但是,类型系统将被归类为不健全,因为类型不变量未被强制执行.

特别是,变量的类型约束仅在赋值时进行检查,因此对使其从子集中删除的对象的修改将导致变量持有它不应该具有的对象,例如

subset OrderedList of List where [<=] @$_;

my OrderedList $list = [1, 2, 3];
$list[0] = 42;
say $list ~~ OrderedList;
Run Code Online (Sandbox Code Playgroud)

您可以使用一些元对象向导来使对象系统在透明防护对象中装箱对象的任何方法调用后自动检查类型.

一个天真的实现可能如下所示:

class GuardHOW {
    has $.obj;
    has $.guard;
    has %!cache =
        gist => sub (Mu \this) {
            this.DEFINITE
                ?? $!obj.gist
                !! "({ self.name(this) })";
        },
        UNBOX => sub (Mu $) { $!obj };

    method find_method(Mu $, $name) {
        %!cache{$name} //= sub (Mu $, |args) {
            POST $!obj ~~ $!guard;
            $!obj."$name"(|args);
        }
    }

    method name(Mu $) { "Guard[{ $!obj.^name }]" }
    method type_check(Mu $, $type) { $!obj ~~ $type }
}

sub guard($obj, $guard) {
    use nqp;
    PRE $obj ~~ $guard;
    nqp::create(nqp::newtype(GuardHOW.new(:$obj, :$guard), 'P6int'));
}
Run Code Online (Sandbox Code Playgroud)

这将使以下失败:

my $guarded-list = guard([1, 2, 3], OrderedList);
$guarded-list[0] = 42;
Run Code Online (Sandbox Code Playgroud)