Conversation

cannot be elaborated to the following record: record { A = U32, len = 3, data = ["a", "b", "c"], } : Record { A : Type, len : A, data : Array len String, ^^^ error: expected `U32`, found `A` }
2
1
I think this error is fine…seems like the issue is that signatures aren’t explicit about which types are opaque/existential. You need to know which U32s to pack as As and which to leave alone (or which As to inline as U32). So why not require e.g. ‘Vector (pub len) String’ here?
1
That is, it seems analogous to a situation like this expression: pack { Int, (1, 2) } Which is missing a signature to specify which Ints to pack and which to leave alone: as ∃t. t × Int So the compiler is doing something like (erroneously) guessing ∃t. t × t.
1
Or do you want to retain the fact that the vector’s length is determined by ‘len’, while also preventing the use of ‘len’ as a U32 elsewhere? (That is, a user *knows* it must be a U32, but cannot *rely* on that fact.) That seems…subtly dependent (ha) on scope, but feasible, idk
1
I see. It does seem like there ought to be a tidier solution than introducing implicit coercions like that, yeah. In a way I guess you need to distinguish ‘U32’ from “some type ‘A’ which is equal to ‘U32’”…
1
1
…in such a way that ‘Vector len String’ is somehow aware that whoever put ‘len’ *in* there must have had a proof that A=U32, but nobody can take it back *out*.
1
1
I do wonder how other dependently typed languages handle with this. Do they prevent you from leaking out implementation details accidentally in signatures, or do they substitute the definition at each usage site?
1