Raku의 매개 변수화 된 유형, 런타임 값을 매개 변수로 사용하는 방법
Raku에 대한 매개 변수화 된 유형 을 만들고 싶습니다 . 기본적으로 속성 중 하나의 값 범위가 주요 차이점 인 몇 가지 다른 클래스를 만들고 싶습니다. 예를 들어, 클래스는 건물의 유형을 나타내며, 3 층 또는 기타 여러 층의 건물에 대해 다른 클래스를 갖고 싶습니다. 그래서 이것이 제가 생각할 수있는 최고입니다.
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;
여러 층 수를 관리해야하는 즉시 이것은 분명히 비실용적입니다 (그라나다에있는 것은 아니지만, 최대 10 층이있는 것 같지만 ...). 여기서 문제는 기본적으로 컴파일 타임에 하위 집합에 대한 정보가 있어야하므로 매크로 를 사용하지 않는 한 (아직 실험적인) 변수를 사용할 수있는 방법이 없습니다. 매개 변수 값에 대해 이러한 종류의 커리 역할 을 정의하는 실용적인 방법을 생각할 수 있습니까?
답변
사실, 이전에 말했듯이 where 절에서 문제없이 조건을 사용할 수 있습니다. 중괄호로 묶기 만하면됩니다.
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
모든 할당 유형을 포함해야합니다.
나는 매우 제한된 MOP 찹을 가지고 있으며 다음은 추악 해 보이지만 작동하며 올바른 방향으로 나아가는 단계 일 수 있습니다.
내가 한 것:
subset
MOP를 통해 10,000 초의 배열을 동적으로 구성했습니다 .시간은
BEGIN
.역할을 매개 변수화하기 위해 배열에서 적절한 요소를 사용했습니다.
my @max-floors-checkers;
BEGIN {
@max-floors-checkers = do for ^10_000 -> \floors {
Metamodel::SubsetHOW.new_type:
refinee => UInt,
refinement => { $^floors <= floors } } } role BuildingCategory[ ::MaxFloorsCheck ] { has MaxFloorsCheck $.floors }
class Capped-at-three does BuildingCategory[ @max-floors-checkers[3] ] {}
my $capped3 = Capped-at-three.new( floors => 2 ); say $capped3.raku; # Capped-at-three.new(floors => 2
my $capped4 = Capped-at-three.new( floors => 4 ); # Type check failed
익명의 where
절을 사용해 보았지만 아무 소용이없는 것과 비슷하지만 문제를 추적했습니다. where
절이 BUILD
메서드에 의해 분명히 무시되고 있습니다. 절 $!floor
을 우회하는 직접 액세스 (를 통해 ) 가 있기 때문인지 where
또는 다른 이상한 일이 진행 중인지 (아마 후자 일 Nil
경우 where
절 에서 매개 변수화 된 값을 사용하려고하면 일반적으로 얻었습니다 ) 확실하지 않습니다 .
그럼에도 불구하고 이것은 유용한 오류 메시지를 제공하는 것을 포함하여 잘 작동합니다.
role Zipi[$condition] {
has $.floor; submethod BUILD(:$floor, |c) {
die "Invalid floor number."
unless $floor ~~ $condition;
$!floor = $floor;
}
}
바닥이 항상이라고 가정 할 수 0 .. x
있거나 x .. y
훨씬 더 유용한 오류 메시지를 제공 할 수 있다면 수정하기가 얼마나 쉬운 지 알 수 있습니다 .
독자가 Java를 알고 있지만 Raku를 아는 경우를 다루는 nanswer.
Collection<String> coll = new LinkedList<String>();
Raku의 매개 변수화 된 유형
링크 된 Java 예제는 다음과 같습니다.
실제 형식 인수가있는 제네릭 형식의 인스턴스화를 매개 변수가있는 형식이라고합니다. 예 (매개 변수화 된 유형) :
Collection<String> coll = new LinkedList<String>();
합리적인 Raku 아날로그는 다음과 같습니다.
my Positional[Str] \coll = Array[Str].new;
Positional유형은 매개 변수화입니다 역할 . 역할은 인터페이스 및 / 또는 유형의 부분 구현을 지정합니다. 나는 Raku 가이 nanswer의 목적을 위해 제공된다는 점 Positional
에서 Java와 충분히 유사 하다고 생각 Collection
합니다.
Array유형은 매개 변수화입니다 클래스 . Positional
역할 을 준수하는 데이터 구조를 지정합니다 . 연결된 목록은 아니지만이 nanswer의 목적에 충분합니다.