La réponse de TL; DR JJ est juste, mais l'explication m'a laissé perplexe. Je vois actuellement le problème que vous avez montré comme un message d' erreur / bogue et / ou d'erreur d' autovivification 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 c'est un bug ou assez proche d'un.
Un bogue / problème s'applique également aux tableaux dans le même scénario:
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
S'il est préférable de considérer notabug, le message d'erreur devrait peut-être être modifié. Bien que je convienne avec JJ que le message d'erreur est en fait sur le point (lorsque vous comprenez comment fonctionne raku et comprenez ce qui se passe), je pense que c'est néanmoins un message d'erreur LTA si nous ne changeons pas raku (do) en dwim.
D'un autre côté, je ne sais pas comment améliorer au mieux le message d'erreur. Et maintenant, nous avons ce SO. (cf mon point à ce sujet dans le message d'erreur LTA? dans une réponse récente que j'ai écrite .)
Une autre solution
J'ai déjà essayé le %
sceau pour la variable de hachage, cela ne fonctionne pas non plus.
JJ a fourni une solution qui initialise avec une valeur avec un explicite .new
. Mais cela supprime la contrainte de la variable. Pour le conserver:
class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;
Idéalement, le constant
ne serait pas nécessaire, et peut-être qu'un jour ce ne sera pas le cas, mais je pense que l'analyse des traits est limitée.