Static Smart Constructors with Double Splices

I plan on using this technique in at least one library, and so thought it would be worth giving a name and a page dedicated to it, so it can be linked to, instead of explained all over again.

Sometimes you’re making a DSL and you need a way to make a smart constructor that is static. You want to validate a value at compile-time (possibly because the validation logic is harder to do in the type-system or not ergonomic enough), and also return the run-time value, without having to lift the whole structure from TH-land to real-land. Perhaps your data type is a funky GADT with functions in it, and therefore has no Lift instance anyway!

One pattern to achieve the desired result is using a double splice.

Here’s a really trivial example with strings:

Note that the notNull validator is well-typed (which is commonly lacking in Template-Haskell, but here works well):

The above uses typed splices $$( ... ) and typed quotes [|| ... ||] . However, you can implement the same technique with regular $(..) and [| .. |] if typed splices are too long for you.

Here is the implementation:

Thanks to Michael Sloan for the idea to have an expression return another expression.

© 2019-08-22 Chris Done