Warm tip: This article is reproduced from serverfault.com, please click

Parametrized types in Raku, how to use run time values as parameters

发布于 2020-11-27 17:54:23

I'd like to create some parametrized types for Raku; basically, I'd like to create some different classes whose main difference would be the range of values of one of its attributes; for instance, classes represent types of building, I'd like to have different classes for buildings with 3 or any other number of floors. So this is the best I could think of:

subset Two-Tops of UInt where * <=2;
subset Three-Tops of UInt where * <=3;

role Zipi[ ::Capper ] {
    has Capper $.floor;
}
    
class Capped-at-three does Zipi[Three-Tops] {}


my $capped = Capped-at-three.new( floor => 2 );
say $capped.raku;

This is clearly unpractical as soon as you need to take care of many different numbers of floors (not here in Granada, where they have at most 10, I think, but well... ). The problem here is basically you need to have the information for subsets at compile time, so unless you use macros (still experimental), there's no way you can use any kind of variable. So can you think of a practical way of defining this kind of curried roles for any value of the parameter?

Questioner
jjmerelo
Viewed
0
user0721090601 2020-11-28 16:51:20

Actually, unlike I said in my previous you can use conditions in where clauses without problem, you just need to encase them in braces:

role Zipi[$condition] {
    has $.floor is rw where {$_ ~~ $condition}
    method foo($x) { $!floor = $x }
}

class A does Zipi[2 < * < 5] {
    method bar($x) { $.floor = $x }
}

#my $a = A.new( floor => 10); # error
my $a = A.new( floor => 4); # OK

#$a.foo(10); # error
$a.foo(3); # OK

#$a.bar(0); # error
$a.bar(4); # OK

#$a.floor = 9; # error
$a.floor = 3; # OK

That should cover all of the assignment types