packages feed

ban-instance 0.1.0.1 → 0.1.1.0

raw patch · 5 files changed

+53/−20 lines, 5 filesdep ~template-haskellnew-uploaderPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: template-haskell

API changes (from Hackage documentation)

Files

ChangeLog.md view
@@ -1,5 +1,9 @@ # Changelog for ban-instance +## 0.1.1.0 - 2026-03-30++* Enable banning instances including type variables.+ ## 0.1.0.1 - 2019-11-08  * Remove broken test.
README.md view
@@ -13,7 +13,7 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE UndecideableInstances #-} -import Lanuage.Haskell.Instance.Ban+import Language.Haskell.Instance.Ban  data Foo = -- ... @@ -69,7 +69,11 @@  ## Limitations -* There is currently no support for type classes with associated types-  or associated data types. * Type quotations `[t|...|]` do not support free variables   ([GHC#5616](https://gitlab.haskell.org/ghc/ghc/issues/5616)).+  To overcome this limitation, `banInstance` allows you to use an explicit+  `forall`. For example:++  ```haskell+  $(banInstance [t|forall a. ToJSON (Maybe a)|] "use a newtype wrapper at the API layer")+  ```
ban-instance.cabal view
@@ -1,5 +1,6 @@+cabal-version:  1.18 name:           ban-instance-version:        0.1.0.1+version:        0.1.1.0 synopsis:       For when a type should never be an instance of a class description:   <<https://raw.githubusercontent.com/qfpl/assets/master/data61-transparent-bg.png>>@@ -19,19 +20,21 @@ bug-reports:    https://github.com/qfpl/ban-instance/issues author:         Jack Kelly, Alex Mason maintainer:     jack.kelly@data61.csiro.au-copyright:      Copyright (C) 2017 Data61+copyright:      (c) 2017, Commonwealth Scientific and Industrial Research Organisation license:        BSD3 license-file:   LICENSE build-type:     Simple-cabal-version:  >= 1.10-tested-with: GHC == 8.0.2-              || == 8.2.2-              || == 8.4.4-              || == 8.6.5-              || == 8.8.1+tested-with: GHC == 8.10.7+              || == 9.0.1+              || == 9.2.7+              || == 9.4.5+              || == 9.6.5+              || == 9.8.2+              || == 9.10.2+              || == 9.12.2 -extra-source-files: ChangeLog.md-                    README.md+extra-doc-files: ChangeLog.md+                 README.md  source-repository head   type: git@@ -40,8 +43,8 @@ library   hs-source-dirs: src   ghc-options: -Wall-  build-depends: base >= 4.7 && < 4.14-               , template-haskell >= 2.11 && < 2.16+  build-depends: base >= 4.7 && < 4.22+               , template-haskell >= 2.16 && < 2.24   exposed-modules: Language.Haskell.Instance.Ban   default-language: Haskell2010 @@ -50,6 +53,6 @@   main-is: Spec.hs   hs-source-dirs: test   ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N-  build-depends: base >= 4.7 && < 4.14+  build-depends: base                , ban-instance   default-language: Haskell2010
src/Language/Haskell/Instance/Ban.hs view
@@ -6,7 +6,7 @@  {-| Module      : Language.Haskell.Instance.Ban-Description : Declare that a typeclass instance+Description : Declare that a typeclass instance should never exist. Copyright   : (c) 2017, Commonwealth Scientific and Industrial Research Organisation License     : BSD3 Maintainer  : jack.kelly@data61.csiro.au@@ -38,6 +38,12 @@ -- @ -- \$(banInstance [t|ToJSON Foo|] "why ToJSON Foo should never be defined") -- @+--+-- To ban instances containing type variables:+--+-- @+-- \$(banInstance [t|forall a. ToJSON (Maybe a)|] "why ToJSON (Maybe a) should never be defined")+-- @ banInstance   :: TypeQ      -- ^ The instance you want to ban.@@ -53,7 +59,7 @@                                   ':$$: 'Text "Instance banned at " ':<>: 'Text $(symbol $ formatLocation loc)                                   ':$$: 'Text ""                                   )|]]-  pure <$> instanceD context constraintQ (convertClassDecs classDecs)+  pure <$> instanceD context (withoutForall <$> constraintQ) (convertClassDecs classDecs)  symbol :: String -> TypeQ symbol = litT . strTyLit@@ -61,10 +67,20 @@ formatLocation :: Loc -> String formatLocation Loc{..} = concat ["[", loc_package, ":", loc_module, "] ", loc_filename, ":",  show $ fst loc_start] +withoutForall :: Type -> Type+withoutForall topTy = go topTy where+  go (ForallT _ _ ty) = go ty+  go ty = ty+ className :: Type -> Name className topTy = go topTy where-  go (AppT ty _) = className ty-  go (ConT name) = name+  go (ForallT _ _ ty)  = className ty+  go (ForallVisT _ ty) = className ty+  go (AppT ty _)       = className ty+  go (AppKindT ty _)   = className ty+  go (SigT ty _)       = className ty+  go (ConT name)       = name+  go (ParensT ty)      = className ty   go _ = error $ "Cannot determine class name for type: " ++ pprint topTy  convertClassDecs :: [Dec] -> [DecQ]
test/Spec.hs view
@@ -2,6 +2,7 @@  {-# LANGUAGE DataKinds              #-} {-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE ImpredicativeTypes     #-} {-# LANGUAGE MultiParamTypeClasses  #-} {-# LANGUAGE RankNTypes             #-} {-# LANGUAGE TemplateHaskell        #-}@@ -22,6 +23,11 @@ -- Test that we haven't overlapped other instances by mistake. instance TestClass Int Int where   testFunction = const 0++class TestClass2 a where+  testFunction2 :: a++$(banInstance [t|forall a. TestClass2 (Maybe a)|] "no instances allowed")  main :: IO () main = pure ()