packages feed

constraints-extras 0.2.3.5 → 0.3

raw patch · 6 files changed

+29/−19 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Constraint.Extras: argDict :: (ArgDict f, ConstraintsFor f c) => f a -> Dict (c a)
+ Data.Constraint.Extras: argDict :: (ArgDict c f, ConstraintsFor f c) => f a -> Dict (c a)
- Data.Constraint.Extras: argDict' :: forall f c g a. (ArgDict f, ConstraintsFor' f c g) => f a -> Dict (c (g a))
+ Data.Constraint.Extras: argDict' :: forall f c g a. (Has' c f g) => f a -> Dict (c (g a))
- Data.Constraint.Extras: argDictV :: forall f c g v. (ArgDict f, ConstraintsForV f c g) => f v -> Dict (c (v g))
+ Data.Constraint.Extras: argDictV :: forall f c g v. (HasV c f g) => f v -> Dict (c (v g))
- Data.Constraint.Extras: class ArgDict f where {
+ Data.Constraint.Extras: class ArgDict (c :: k -> Constraint) (f :: k -> *) where {
- Data.Constraint.Extras: type ArgDictV f = ArgDict f
+ Data.Constraint.Extras: type ArgDictV f c = ArgDict f c
- Data.Constraint.Extras: type Has (c :: k -> Constraint) f = (ArgDict f, ConstraintsFor f c)
+ Data.Constraint.Extras: type Has (c :: k -> Constraint) f = (ArgDict c f, ConstraintsFor f c)
- Data.Constraint.Extras: type Has' (c :: k -> Constraint) f (g :: k' -> k) = (ArgDict f, ConstraintsFor' f c g)
+ Data.Constraint.Extras: type Has' (c :: k -> Constraint) f (g :: k' -> k) = (ArgDict (ComposeC c g) f, ConstraintsFor' f c g)
- Data.Constraint.Extras: type HasV c f g = (ArgDict f, ConstraintsForV f c g)
+ Data.Constraint.Extras: type HasV c f g = (ArgDict (FlipC (ComposeC c) g) f, ConstraintsForV f c g)
- Data.Constraint.Extras.TH: gadtIndices :: Name -> Q [Either Type Type]
+ Data.Constraint.Extras.TH: gadtIndices :: Name -> Name -> Q [Either Type Type]

Files

ChangeLog.md view
@@ -1,5 +1,9 @@ # Revision history for constraints-extras +## 0.3 - 2019-05-16++* Added a parameter for the type class, to allow for custom not-fully-polymorphic instances of ArgDict in cases where e.g. your key type contains dictionaries for specific classes. You will now need FlexibleInstances, MultiParamTypeClasses for the instances created by deriveArgDict.+ ## 0.2.3.5 - 2019-05-04  * Bumped version bounds on base and template-haskell to admit the versions from GHC 8.6.x
README.lhs view
@@ -12,6 +12,8 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications  #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ExistentialQuantification #-} 
README.md view
@@ -12,6 +12,8 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications  #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ExistentialQuantification #-} 
constraints-extras.cabal view
@@ -1,5 +1,5 @@ name: constraints-extras-version: 0.2.3.5+version: 0.3 synopsis: Utility package for constraints description: Convenience functions and TH for working with constraints. See <https://github.com/obsidiansystems/constraints-extras/blob/develop/README.md README.md> for example usage. category: Constraints
src/Data/Constraint/Extras.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PolyKinds #-}@@ -26,27 +27,29 @@ -- at the moment, it appears to require honest type level functions. (Closed type families which must be fully -- applied didn't quite cut it when I tried). Some symbolic type-level application could do the trick, but I didn't -- want to go quite that far at the time of writing.-class ArgDict f where++class ArgDict (c :: k -> Constraint) (f :: k -> *) where   type ConstraintsFor f (c :: k -> Constraint) :: Constraint   argDict :: ConstraintsFor f c => f a -> Dict (c a)  type ConstraintsFor' f (c :: k -> Constraint) (g :: k' -> k) = ConstraintsFor f (ComposeC c g) -argDict' :: forall f c g a. (ArgDict f, ConstraintsFor' f c g) => f a -> Dict (c (g a))+argDict' :: forall f c g a. (Has' c f g) => f a -> Dict (c (g a)) argDict' tag = case argDict tag of   (Dict :: Dict (ComposeC c g a)) -> Dict+ type ConstraintsForV (f :: (k -> k') -> *) (c :: k' -> Constraint) (g :: k) = ConstraintsFor f (FlipC (ComposeC c) g) -argDictV :: forall f c g v. (ArgDict f, ConstraintsForV f c g) => f v -> Dict (c (v g))+argDictV :: forall f c g v. (HasV c f g) => f v -> Dict (c (v g)) argDictV tag = case argDict tag of   (Dict :: Dict (FlipC (ComposeC c) g a)) -> Dict  {-# DEPRECATED ArgDictV "Just use 'ArgDict'" #-}-type ArgDictV f = ArgDict f+type ArgDictV f c = ArgDict f c -type Has (c :: k -> Constraint) f = (ArgDict f, ConstraintsFor f c)-type Has' (c :: k -> Constraint) f (g :: k' -> k) = (ArgDict f, ConstraintsFor' f c g)-type HasV c f g = (ArgDict f, ConstraintsForV f c g)+type Has (c :: k -> Constraint) f = (ArgDict c f, ConstraintsFor f c)+type Has' (c :: k -> Constraint) f (g :: k' -> k) = (ArgDict (ComposeC c g) f, ConstraintsFor' f c g)+type HasV c f g = (ArgDict (FlipC (ComposeC c) g) f, ConstraintsForV f c g)  has :: forall c f a r. (Has c f) => f a -> (c a => r) -> r has k r | (Dict :: Dict (c a)) <- argDict k = r
src/Data/Constraint/Extras/TH.hs view
@@ -10,11 +10,10 @@ import Control.Monad import Language.Haskell.TH - deriveArgDict :: Name -> Q [Dec] deriveArgDict n = do-  ts <- gadtIndices n   c <- newName "c"+  ts <- gadtIndices c n   let xs = flip map ts $ \case         Left t -> AppT (AppT (ConT ''ConstraintsFor) t) (VarT c)         Right t -> (AppT (VarT c) t)@@ -23,16 +22,16 @@   arity <- tyConArity n   tyVars <- replicateM (arity - 1) (newName "a")   let n' = foldr (\v x -> AppT x (VarT v)) (ConT n) tyVars-  [d| instance ArgDict $(pure n') where+  [d| instance ArgDict $(varT c) $(pure n') where         type ConstraintsFor  $(pure n') $(varT c) = $(pure constraints)-        argDict = $(LamCaseE <$> matches n 'argDict)+        argDict = $(LamCaseE <$> matches c n 'argDict)     |]  {-# DEPRECATED deriveArgDictV "Just use 'deriveArgDict'" #-} deriveArgDictV = deriveArgDict -matches :: Name -> Name -> Q [Match]-matches n argDictName = do+matches :: Name -> Name -> Name -> Q [Match]+matches c n argDictName = do   x <- newName "x"   reify n >>= \case     TyConI (DataD _ _ _ _ cons _) -> fmap concat $ forM cons $ \case@@ -41,7 +40,7 @@       ForallC _ _ (GadtC [name] bts (AppT _ (VarT b))) -> do         ps <- forM bts $ \case           (_, AppT t (VarT b')) | b == b' -> do-            hasArgDictInstance <- not . null <$> reifyInstances ''ArgDict [t]+            hasArgDictInstance <- not . null <$> reifyInstances ''ArgDict [VarT c, t]             return $ if hasArgDictInstance               then Just x               else Nothing@@ -74,15 +73,15 @@    TyConI (DataD _ _ ts mk _ _) -> fromMaybe 0 (fmap kindArity mk) + length ts    _ -> error $ "tyConArity: Supplied name reified to something other than a data declaration: " ++ show n -gadtIndices :: Name -> Q [Either Type Type]-gadtIndices n = reify n >>= \case+gadtIndices :: Name -> Name -> Q [Either Type Type]+gadtIndices c n = reify n >>= \case   TyConI (DataD _ _ _ _ cons _) -> fmap concat $ forM cons $ \case     GadtC _ _ (AppT _ typ) -> return [Right typ]     ForallC _ _ (GadtC _ bts (AppT _ (VarT _))) -> fmap concat $ forM bts $ \case       (_, AppT t (VarT _)) -> do-        hasArgDictInstance <- fmap (not . null) $ reifyInstances ''ArgDict [t]+        hasArgDictInstance <- fmap (not . null) $ reifyInstances ''ArgDict [VarT c, t]         return $ if hasArgDictInstance then [Left t] else []       _ -> return []     ForallC _ _ (GadtC _ _ (AppT _ typ)) -> return [Right typ]     _ -> return []-  a -> error $ "gadtResults: Unmatched 'Info': " ++ show a+  a -> error $ "gadtIndices: Unmatched 'Info': " ++ show a