Robin Green wrote:
> Well, not really - or not the proof you thought you were getting. As I
> am constantly at pains to point out, in a language with the possibility
> of well-typed, non-terminating terms, like Haskell, what you actually
> get is a "partial proof" - that *if* the expression you are demanding
> terminates, you will get a value of the correct type.
I only want to point out that the above "terminates" actually is "can be
put in NF", since putting the expression in WHNF is not enough. In other
words, you need deepSeq, not seq when forcing/checking proofs.
To partially mitigate this problem, I believe strictness annotations can
be used, as in
data Nat t where
Z :: Nat Zero
S :: ! Nat t -> Nat (Succ t)
Now one could safely write
foo :: Nat t -> A t -> B
foo proof value = proof `seq`
-- here you can assume t to be a finite type-level natural
If proof is invalid, foo will return _|_.
Using no strictess annotation, but still using seq instead of deepSeq,
the code above would be unsafe, since one can always pass (S undefined)
as proof.
Using seq also allows to check the proof in constant time (neglecting
the proof generation time, of course). deepSeq instead would require
traversing the proof each time one wants to check it, e.g. in different
functions.
Does anyone else believe that using strictess annotations in GADT proof
terms would be good style?
Zun.