Skip to main content

You are not logged in. Your edit will be placed in a queue until it is peer reviewed.

We welcome edits that make the post easier to understand and more valuable for readers. Because community members review edits, please try to make the post substantially better than how you found it, for example, by fixing grammar or adding additional resources and hyperlinks.

3
  • $\begingroup$ I tried writing mappings between Value (struct ts) and All Value ts using both your solutions, fully inlined All and a Value defined as a data type. Your second solution and full inlining required to match on (implicit) ts, while the others allowed to directly match on Value (which is maybe convenient? at least less verbose). Since I don't know if GADT approach will bring any advantages, I'll go with your first solution for now since it doesn't require casts between Value nat and Nat. Thanks for an answer. $\endgroup$ Commented Oct 14, 2022 at 19:57
  • $\begingroup$ Requiring some kind of mutual definition here is a pretty well-known shortcoming of Agda's termination checker. The check is just not very compositional, and recursive definitions can't just be inlined for the checker to 'see through' them. This is the reason that sized types were invented, and although I'm not a great fan of them, I'm also not aware of any other promising solutions. $\endgroup$
    – Dan Doel
    Commented Oct 15, 2022 at 18:48
  • $\begingroup$ On the flip side: most rigorous specifications of inductive definitions I'm aware of would say that Type is not an actual specification, and it must be compiled into essentially a mutual definition between Type and List Type. Then it is no surprise that recursive definitions on Type require a mutual definition on List Type. The foundational accounts for inductive definitions themselves fail to be compositional in the same way as Agda's termination checker. (Possibly recent work by Henning Basold does not have this problem.) $\endgroup$
    – Dan Doel
    Commented Oct 15, 2022 at 19:04