I don't think that Code using new for object construction. It's a very base level class. Per the source code, what's actually needed is a Callable, and that's a simple role to apply any class. Personally I would have expected it to call CALL-ME
For your second example, we can find
multi sub postcircumfix:<[ ]>( \SELF, Any:D \pos ) is raw {
SELF.AT-POS(pos.Int);
}
So if the type isn't contemplated in advance, it will just try to coerce to Int which your class doesn't have.
Your first one SHOULD work by simply changing it to
class Foo does Callable {
method POSITIONS(\foo) { 1 }
};
my Foo $foo .= new;
say <a b c>[$foo]
However this errors, complaining that Foo doesn't implement .pos. That function isn't documented in source that I can see but implementing it does make things magically work:
class Foo does Callable {
method POSITIONS(|c) { (0,1,2,(0,1),(0,2),(1,2),(0,1,2),(0..2)).pick }
method pos(|c) { self.POSITIONS: c }
};
my Foo $foo .= new;
say <a b c>[$foo]
The positional argument that's passed to pos is the list that's being sliced ( (a b c) in your example), in case you want to adjust the slice based on the array contents, grep/map style.
Edit:
Actually, foolish me. pos was renamed to POSITIONS and TIO (that I was testing on) isn't updated. Because of that change, I would recommend using both pos and POSITIONS, just calling POSITIONS inside of pos for anyone on older implementations.