Suppose I have the following code:
my constant @suits = <Clubs Hearts Spades Diamonds>;
my constant @values = 2..14;
class Card {
has $.suit;
has $.value;
# order is mnemonic of "$value of $suit", i.e. "3 of Clubs"
multi method new($value, $suit) {
return self.bless(:$suit, :$value);
}
}
It defines some suits and some values and what it means to be a card.
Now, to build a deck, I essentially need to take the cross product of the suits and the values and apply that to the constructor.
The naiive approach to do this, would of course be to just iterate with a loop:
my @deck = gather for @values X @suits -> ($v, $c) {
take Card.new($v, $c);
}
But this is Raku, we have a cross
function that can take a function as an optional argument!, so of course I'm gonna do that!
my @deck = cross(@values, @suits, :with(Card.new));
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
... wait no. What about this?
my @deck = cross(@values, @suits):with(Card.new);
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
Still nothing. Reference maybe?
my @deck = cross(@values, @suits):with(&Card.new);
# ===SORRY!=== Error while compiling D:\Code\Raku/.\example.raku
# Illegally post-declared type:
# Card used at line 36
I read somewhere I can turn a function into an infix operator with []
my @deck = cross(@values, @suits):with([Card.new]);
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
That also doesn't work.
If classes are supposed to just be modules, shouldn't I then be able to pass a function reference?
Also why is it saying 'with' is that's unexpected? If I'm intuiting this right, what it's actually complaining about is the type of the input, rather than the named argument.