Прежде всего, разделитель кейсов довольно тупой и не зависит от проверки типов в данный момент. Прежде всего, он создает каждое дело и спрашивает, проверяет ли ветка типов, допустима ли эта ветвь.
Я нашел минимальный пример, который показывает похожие проблемы.
data PreVec : Nat -> Type where
VCons : PreVec n
data Bad : {tipe1 : Type} -> tipe1 -> Type where
MkBad : Bad VCons
data Good1 : PreVec n -> Type where
MkGood1 : Good1 VCons
data Bad2 : {tipe1: Type} -> tipe1 -> Type where
MkBad2 : {n: Nat} -> Bad2 (VCons {n})
Использование их в аналогичнойway выдаст ошибки на плохих конструкторах, но нахожу на хороших.
Не могу сказать, что полностью понимаю проблему, но, похоже, это в основном связано с порядком разрешения для таких имплицитов, как типы, это, вероятно, ошибка компилятора. По сути, неявное значение tipe1
зависит от переменной n
, которая упакована в самом конструкторе. Я предполагаю, что имплициты в типе заполняются до открытия конструктора, так что n
не входит в область действия типа шаблона.
Кажется, есть несколько патчей, чтобы исправить это. Если переменная tipe1 (или tipe2) сделана явной, а не неявной, случается, что использование _
везде правильно синтезирует тип для вашего примера. Кроме того, изменение типа возвращаемого значения на:
PC (the (PreVec elemType (NSucc nwhole)) (VCons PC elemType (NSucc nwhole) n1 h1 pf1))
(VCons PC elemType (NSucc nwhole) n2 h2 pf2)
также успешно. Одна вещь, которая не удалась, - это поменять все остальные неявные на явные, это касается только этих tipe1 и tipe2. Каждый их экземпляр в конструкторах ограничен, поэтому нет проблем с самим типом. Такая ситуация возникает только при сопоставлении с образцом.