fosskers/versions

Define a `Lift` version for `Version` and related data types

RyanGlScott opened this issue · 6 comments

It is very useful to be able to call the version function within a Template Haskell splice so that one can throw a compile-time error if the version number is malformed:

ver :: Text -> Q Exp
ver nm =
  case Versions.version nm of
    Left err -> fail (errorBundlePretty err)
    Right v  -> lift v

Currently, this function doesn't work out of the box, as the Version data type (which version returns) does not define a Lift instance. As a result, we have to define our own orphan Lift instances to make this work.

Would you be OK with defining the Lift instances directly in the versions library? Something like this would suffice:

deriving instance Lift Chunk
deriving instance Lift Chunks
deriving instance Lift Release
deriving instance Lift Version

Sure. Can you suggest a unit test that could be used to verify it?

@RyanGlScott Can you test the linked PR and see if it works for you? If so I'll make a release.

Thanks, @fosskers! That PR gives me exactly what I need.

Can you suggest a unit test that could be used to verify it?

The way we are using this functionality in the what4 library is something like:

ver :: Text -> Q Exp
ver nm =
  case Versions.version nm of
    Left err -> fail (errorBundlePretty err)
    Right v  -> lift v

... $(ver "0") ...

So you could test something like $(ver "0") == Version {_vEpoch = Nothing, _vChunks = Chunks (Numeric 0 :| []), _vRel = Nothing, _vMeta = Nothing}, or perhaps even prettyVer $(ver "0") == "0".

You could also test that supplied an invalid version throws a compile-time error, e.g., $(recover [| () {- Recovery fallback -} |] (ver "!!!")) == ().

Thanks a lot, I'll incorporate those!

Released as 6.0.2.