Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple utility for COMPLETE pragmas #17

Open
treeowl opened this issue Sep 30, 2022 · 1 comment
Open

Simple utility for COMPLETE pragmas #17

treeowl opened this issue Sep 30, 2022 · 1 comment

Comments

@treeowl
Copy link
Contributor

treeowl commented Sep 30, 2022

I dunno if it belongs here, but COMPLETE pragmas are a bit painful to write by hand for types with many constructors, especially when constructors can be added or removed from time to time. Using th-abstraction, it's easy to fix this. Without th-abstraction, I don't wanna.

import Language.Haskell.TH.Datatype (DatatypeInfo (..), ConstructorInfo(..), reifyDatatype)
import Language.Haskell.TH (Q, Dec, Name, pragCompleteD)
import Data.List ((\\))

-- | Produce a @COMPLETE@ pragma for a type with many constructors,
-- without having to list them all out.
--
-- @completeWithButWithout ''T ['P] ['C1, 'C2]@ produces a @COMPLETE@
-- pragma stating that pattern matching on the type @T@ is complete with
-- with the pattern @P@ and with all the constructors of @T@ other than
-- @C1@ and @C2@.
completeWithButWithout :: Name -> [Name] -> [Name] -> Q [Dec]
completeWithButWithout ty extra_patterns excl_constrs = do
  di <- reifyDatatype ty
  let constrs = map constructorName (datatypeCons di)
  (:[]) <$> pragCompleteD (extra_patterns ++ (constrs \\ excl_constrs))
                          (Just ty)

For truly enormous datatypes, (\\) could be swapped out in favor of something that uses the Ord Name instance.

@mgsloan
Copy link
Collaborator

mgsloan commented Oct 1, 2022

Yeah, seems useful! I'd merge a PR adding such a thing. I suppose putting it in its own module makes sense as TH.Utilities is a grab-bag of utilities useful for writing TH code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants