TL; DR JJ odpowiedź jest słuszna, ale wyjaśnienie mnie pomieszało. Obecnie widzę problem, który pokazałeś jako komunikat o błędzie / błędzie automatycznej weryfikacji i / lub komunikat o błędzie LTA.
say my Any $Any; # (Any)
say my Hash $Hash; # (Hash)
say my Hash[Int] $Hash-Int; # (Hash[Int])
$Any<a> = 42; # OK
$Hash<a> = 42; # OK
$Hash-Int.new<a> = 42; # OK
$Hash-Int<a> = 42; # must be an object instance, not a type object
Imo, to jest błąd lub bardzo blisko jednego.
Błąd / problem dotyczy również tablic w tym samym scenariuszu:
say my Any $Any; # (Any)
say my Array $Array; # (Array)
say my Array[Int] $Array-Int; # (Array[Int])
$Any[42] = 42; # OK
$Array[42] = 42; # OK
$Array-Int.new[42] = 42; # OK
$Array-Int[42] = 42; # Type check failed ... expected Array[Int] but got Array
Jeśli najlepiej to uznać za notabug, być może komunikat o błędzie powinien zostać zmieniony. Chociaż zgadzam się z JJ, że komunikat o błędzie jest rzeczywiście na miejscu (kiedy zrozumiesz, jak działa raku i zorientujesz się, co się dzieje), myślę, że mimo to jest to komunikat o błędzie LTA, jeśli nie zmienimy raku (do) na dwim.
Jeśli chodzi o chwytającą rękę, nie jest dla mnie oczywiste, jak najlepiej poprawić komunikat o błędzie. A teraz mamy to SO. (por. moje zdanie na ten temat w Czy komunikat o błędzie LTA? w ostatniej odpowiedzi, którą napisałem .)
Inne rozwiązanie
Próbowałem już %
sigil dla zmiennej hash, to też nie działa.
JJ dostarczył rozwiązanie, które inicjuje się wartością jawną .new
. Ale to usuwa ograniczenie ze zmiennej. Aby to zachować:
class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;
Idealnie constant
nie byłoby to potrzebne, a może kiedyś nie będzie, ale myślę, że analiza cech jest ograniczona.