Raku 对中缀的模糊调用(Hyper:Dan::Series,Int)

p6s*_*eve 8 raku

我正在编写一个模型系列类(有点像 pandas 中的类) - 它应该是位置和关联的。

class Series does Positional does Iterable does Associative {
    has Array $.data is required;
    has Array $.index;

    ### Construction ###

    method TWEAK {
        # sort out data-index dependencies
        $!index = gather {
            my $i = 0;
            for |$!data -> $d {
                take ( $!index[$i++] => $d )
            }
        }.Array
    }

    ### Output ### 

    method Str {
        $!index
    }   

    ### Role Support ### 

    # Positional role support
    # viz. https://docs.raku.org/type/Positional

    method of {
        Mu  
    }   
    method elems {
        $!data.elems
    }   
    method AT-POS( $p ) { 
        $!data[$p]
    }   
    method EXISTS-POS( $p ) { 
        0 <= $p < $!data.elems ?? True !! False
    }   

    # Iterable role support
    # viz. https://docs.raku.org/type/Iterable

    method iterator {
        $!data.iterator
    }   
    method flat {
        $!data.flat
    }   
    method lazy {
        $!data.lazy
    }   
    method hyper {
        $!data.hyper
    }   

    # Associative role support
    # viz. https://docs.raku.org/type/Associative

    method keyof {
        Str(Any)
    }   
    method AT-KEY( $k ) { 
        for |$!index -> $p {
            return $p.value if $p.key ~~ $k
        }   
    }   
    method EXISTS-KEY( $k ) { 
        for |$!index -> $p {
            return True if $p.key ~~ $k
        }   
    }   

    #`[ solution attempt #1 does NOT get called
    multi method infix(Hyper: Series, Int) is default {
        die "I was called"
    }
    #]
}

my $s = Series.new(data => [rand xx 5], index => [<a b c d e>]);

say ~$s;
say $s[2];
say $s<b>;
Run Code Online (Sandbox Code Playgroud)

到目前为止非常酷。

我可以dd $s.hyper去拿这个

HyperSeq.new(configuration => HyperConfiguration.new(batch => 64, degree => 1))
Run Code Online (Sandbox Code Playgroud)

但是(必须有一个但是即将到来),我希望能够对我的系列元素进行超级数学,例如:

say $s >>+>> 2;
Run Code Online (Sandbox Code Playgroud)

但这会产生:

Ambiguous call to 'infix(Hyper: Dan::Series, Int)'; these signatures all match:
  (Hyper: Associative:D \left, \right, *%_)
  (Hyper: Positional:D \left, \right, *%_)
  in block <unit> at ./synopsis-dan.raku line 63
Run Code Online (Sandbox Code Playgroud)

我怎样才能告诉我的班级系列不提供联想超级候选人......?


注意:根据 @raiph 的评论将示例编辑为可运行的 MRE ...因此,我根据 docs.raku.org 保留了对 3 个角色的最低要求

p6s*_*eve 3

经过一些实验(以及从一路上非常有用的评论中考虑的新方向),我想我已经找到了一个解决方案:

  1. does Associative从类声明中删除角色,如下所示:
class Series does Positional does Iterable {...}
Run Code Online (Sandbox Code Playgroud)

  1. 将关联角色支持方法保留在类的主体中:
    # Associative role support
    # viz. https://docs.raku.org/type/Associative

    method keyof {
        Str(Any)
    }   
    method AT-KEY( $k ) { 
        for |$!index -> $p {
            return $p.value if $p.key ~~ $k
        }   
    }   
    method EXISTS-KEY( $k ) { 
        for |$!index -> $p {
            return True if $p.key ~~ $k
        }   
    }   
Run Code Online (Sandbox Code Playgroud)

这给了我位置和关联访问器,以及功能性超数学运算符:

my $s = Series.new(data => [rand xx 5], index => [<a b c d e>]);

say ~$s;        #([a => 0.6137271559776396 b => 0.7942959887386045 c => 0.5768018697817604 d => 0.8964323560788711 e => 0.025740150933493577] , dtype: Num)

say $s[2];      #0.7942959887386045
say $s<b>;      #0.5768018697817604
say $s >>+>> 2; #(2.6137271559776396 2.7942959887386047 2.5768018697817605 2.896432356078871 2.0257401509334936)
Run Code Online (Sandbox Code Playgroud)

虽然这感觉有点单薄(并且可能缺乏全套关联函数),但我相当有信心基本方法将为我提供精简的访问权限,就像我寻求的关键功能的哈希一样。并且它不再产生不明确的调用。

这个解决方案可能有点作弊,因为我知道我会接受的妥协程度;-)。