Proposal: liftData for Template Haskell

adam vogt vogt.adam at
Thu May 14 22:11:57 UTC 2015

On Wed, May 13, 2015 at 6:13 AM, Merijn Verstraaten <merijn at>
> Is there any reason we can't have GHC derive Lift instance automatically?
I know there's already a TH library for this, but I guess I don't see why
GHC can't derive them for us. Additionally, the lack of lift instances is
really a pain for a lot of compile time evaluation tricks.

There are two libraries to get your orphan Lift instances: th-orphans and

Here's a list of what should be all the Lift instances on hackage: <>. There are many
duplicates. Text and Double instances happen quite often (9 in ~ 715
packages depending on template-haskell):

Text (Lazy or Strict)
  ./persistent-template-2.1.3/Database/Persist/TH.hs -- indirectly via a
Lift' class


Those orphans could be removed if we had instance Data a => Lift a, because
those types have a mostly sane Data instance. While there are some
differences in the Double instances:

lift x = [| read $(lift (show x)) |] -- in

lift d = [| D# $(return (LitE (DoublePrimL (toRational d)))) |]

lift d = [| fromRational $(litE . rationalL . toRational $ d) :: Double |]

lift = lift . toRational

$(lift (0/0)) is wrong for most instances already: going through Rational
gives -Infinity. Incidentally dataToExpQ (const Nothing) (0/0) also gives

Another difference is whether :t $(lift (1.0 :: Double)) is Double,
Fractional a => a, Read a => a, or something else.

Apart from those two issues, it seems that the duplicated Lift instances do
the same thing as liftData, so the "adding an import will change the
program's runtime behavior" seems rare compared with "adding an import
breaks your program because we didn't agree to put the orphans in one
package only".

So I'm:

+1 on Data a => Lift a
+1 on the DefaultSignatures, if the overlapping instance won't happen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Libraries mailing list