Ghosts of Departed Proofs Convenience

Following on from Ghosts of Departed Proofs with a Named type as defined in Olliver Charles’s post on the same topic, we can add a usability improvement by defining a SomeNamed existential in order to wrap up the new type introduced for the n in Name n a , and then a pattern synonym to conveniently unwrap that constructor.

With this, we can write

And now we have a named version of x ! This scales to any number of tuples or pattern matches. See below for a real example.

Some proof generators

For the sake of example in the next section, I introduce a couple trivial modules for checking non-zeroness of a number, and a function that makes use of such proof to perform division.

Example use

Here’s a simple program that parses two numbers, checks that the latter is non-zero, and then does a division by that non-zero number. Trivial, but it helps demonstrate the syntax without untidiness.

One nice addition is that we can use monad syntax to name them very conveniently!

With an Either E return type, we could return or throw an exception, if we wanted to.

Proof is in the pudding: Examples that do not compile

Here are some example variations of Main which fail to compile, demonstrating that this technique is helping the program be more correct:

This version of main fails to compile simply because I haven’t named the numeratorInt .

Yields the error:

Couldn't match expected type ‘Named x0 Double’ with actual type ‘Double’

Here is a version where I got the arguments to divide the wrong way round:

Yields the error:

• Couldn't match type ‘n’ with ‘n1’

The denominatorNonZero proof refers to denominatorInt by a generate name type ( n1 ), and numeratorInt ’s name ( n ) is different.

© 2019-12-07 Chris Done