La respuesta de TL; DR JJ es correcta, pero la explicación me dejó confundido. Actualmente veo el problema que mostró como un error / error de autovivificación y / o un mensaje de error 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, esto es un error o bastante cerca de uno.
También se aplica un error / problema para las matrices en el mismo escenario:
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
Si se considera mejor notabug, entonces tal vez se deba cambiar el mensaje de error. Si bien estoy de acuerdo con JJ en que el mensaje de error está realmente en punto (cuando entiendes cómo funciona el raku y descubres lo que está sucediendo), creo que, sin embargo, es un mensaje de error de LTA si no cambiamos el raku (do) a dwim.
Por otro lado, no es obvio para mí cómo se puede mejorar el mensaje de error. Y ahora tenemos este SO. (cf mi punto sobre eso en ¿Es el ... mensaje de error LTA? en una respuesta reciente que escribí ).
Otra solución
Ya probé el %
sigilo para la variable hash, que tampoco funciona.
JJ ha proporcionado una solución que se inicializa con un valor explícito .new
. Pero eso elimina la restricción de la variable. Para retenerlo:
class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;
Idealmente constant
, no sería necesario, y tal vez algún día no sea necesario, pero creo que el análisis de rasgos es limitado.