RFC: Singleton equality witnesses

Richard Eisenberg eir at cis.upenn.edu
Wed Feb 6 19:33:36 CET 2013

On Feb 6, 2013, at 1:03 PM, Gabor Greif wrote:

> On 2/5/13, Richard Eisenberg <eir at cis.upenn.edu> wrote:
>> My argument would be not to return
>>  Maybe (SameSing kparam a b)
>> but to return
>>  Either (SameSing kparam a b) (SameSing kparam a b -> Void)
>> or something similar. (Void is taken from the void package, but it could
> I see where you want to get at and recognize the added value. I have
> two thoughts to add, though.
>  o most people are comfortable with assembling equality evidence (for
> example by means of the Maybe monad), but few have done this for its
> refutations.
>  o sometimes an equality proof is just what you need to proceed,
> which is probably a smaller data structure to be created (laziness may
> help here, but still allocates).

I agree with these points, and I would want a function that returns Maybe … to be available. Essentially, I want what you've written -- a general "decide" function with a "semi-decide" wrapper. Programmers can choose not to implement the "decide" function if they don't want/need to.

> I also flipped the type arguments to Either, since 'Right' sounds like
> "Yep" and should signify positive evidence. I believe the ErrorT monad
> transformer also uses this convention.

Wholeheartedly agreed.

>> Also, why generalize the return type with SameSing? Do you have a case where
>> you would want the equality witness type to be other than (:~:)?
> This leaves open the possibility of non-constructivistic evidence (is
> there such a thing?). For example I could imagine an infinite Nat-like
> type (with different representation) where we have a refutation proof
> that n < m-1 and a refutation of n > m+1, and this would allow us to
> construct evidence for n=m. I have seen
> http://queuea9.wordpress.com/2012/11/05/canonize-this/ (and more
> recent ones).

This I'm not so sure of. I think that the evidence returned by sameSing needs to be isomorphic to (a ~ b) in some way for sameSing to be useful. While I can imagine more elaborate structures than (:~:) that can be reduced to (~), those structures then could also be reduced to (:~:). So, I think the generality remains even if you remove the associated type.

>> I've thrown together a wiki page at
>> http://hackage.haskell.org/trac/ghc/wiki/TypeLevelReasoning with Gabor's
>> code, my code, and some of my thoughts. Please add your thoughts and any
>> ideas into the mix!
> I have commented on PropNot, suggesting alternatives.
+1 for Refuted.

To define decideSing for Nat and Symbol, I think we would need to refine eqSingNat and eqSingSymbol to become decideSingNat and decideSingSymbol, using unsafeCoerce for both branches. If Nat and Symbol were real inductive kinds under the hood, the unsafeCoerce would be unnecessary; it is essentially an optimization here.

The only thing that stops me from saying "push" is that I think there is a better organization for all of this. The ideas we're discussing here (things like the Void type) don't seem to belong in TypeLits -- it has nothing to do with literals. Time for a GHC.TypeReasoning module? Does someone have a better name?


More information about the ghc-devs mailing list