packages feed

traverse-with-class 0.2.0.4 → 1.0.0.0

raw patch · 9 files changed

+146/−87 lines, 9 filesdep +tastydep +tasty-hunitdep +traverse-with-classdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: tasty, tasty-hunit, traverse-with-class

Dependency ranges changed: base

API changes (from Hackage documentation)

- Data.Generics.Traversable: everything :: forall r a c p. (Rec c a, ?c :: p c) => (r -> r -> r) -> (forall d. (Rec c d) => d -> r) -> a -> r
+ Data.Generics.Traversable: everything :: forall c r a. (Rec c a) => (r -> r -> r) -> (forall d. (Rec c d) => d -> r) -> a -> r
- Data.Generics.Traversable: everywhere :: forall a c p. (Rec c a, ?c :: p c) => (forall d. (Rec c d) => d -> d) -> a -> a
+ Data.Generics.Traversable: everywhere :: forall c a. (Rec c a) => (forall d. (Rec c d) => d -> d) -> a -> a
- Data.Generics.Traversable: everywhere' :: forall a c p. (Rec c a, ?c :: p c) => (forall d. (Rec c d) => d -> d) -> a -> a
+ Data.Generics.Traversable: everywhere' :: forall c a. (Rec c a) => (forall d. (Rec c d) => d -> d) -> a -> a
- Data.Generics.Traversable: everywhereM :: forall m a c p. (Monad m, Rec c a, ?c :: p c) => (forall d. (Rec c d) => d -> m d) -> a -> m a
+ Data.Generics.Traversable: everywhereM :: forall c m a. (Monad m, Rec c a) => (forall d. (Rec c d) => d -> m d) -> a -> m a
- Data.Generics.Traversable: gfoldMap :: (Monoid r, GTraversable c a, ?c :: p c) => (forall d. (c d) => d -> r) -> a -> r
+ Data.Generics.Traversable: gfoldMap :: forall c r a. (Monoid r, GTraversable c a) => (forall d. (c d) => d -> r) -> a -> r
- Data.Generics.Traversable: gfoldl' :: (GTraversable c a, ?c :: p c) => (forall d. (c d) => r -> d -> r) -> r -> a -> r
+ Data.Generics.Traversable: gfoldl' :: forall c a r. (GTraversable c a) => (forall d. (c d) => r -> d -> r) -> r -> a -> r
- Data.Generics.Traversable: gfoldr :: (GTraversable c a, ?c :: p c) => (forall d. (c d) => d -> r -> r) -> r -> a -> r
+ Data.Generics.Traversable: gfoldr :: forall c a r. (GTraversable c a) => (forall d. (c d) => d -> r -> r) -> r -> a -> r
- Data.Generics.Traversable: gmap :: (GTraversable c a, ?c :: p c) => (forall d. (c d) => d -> d) -> a -> a
+ Data.Generics.Traversable: gmap :: forall c a. (GTraversable c a) => (forall d. (c d) => d -> d) -> a -> a
- Data.Generics.Traversable: gmapM :: (Monad m, GTraversable c a, ?c :: p c) => (forall d. (c d) => d -> m d) -> a -> m a
+ Data.Generics.Traversable: gmapM :: forall c m a. (Monad m, GTraversable c a) => (forall d. (c d) => d -> m d) -> a -> m a
- Data.Generics.Traversable: gtraverse :: (GTraversable c a, Applicative f, ?c :: p c) => (forall d. c d => d -> f d) -> a -> f a
+ Data.Generics.Traversable: gtraverse :: (GTraversable c a, Applicative f) => (forall d. c d => d -> f d) -> a -> f a
- Data.Generics.Traversable.Zipper: query :: (forall a. Rec c a => a -> b) -> Zipper c a -> b
+ Data.Generics.Traversable.Zipper: query :: (forall d. Rec c d => d -> b) -> Zipper c a -> b
- Data.Generics.Traversable.Zipper: trans :: (forall a. Rec c a => a -> a) -> Zipper c a -> Zipper c a
+ Data.Generics.Traversable.Zipper: trans :: (forall d. Rec c d => d -> d) -> Zipper c a -> Zipper c a
- Data.Generics.Traversable.Zipper: transM :: Monad m => (forall a. Rec c a => a -> m a) -> Zipper c a -> m (Zipper c a)
+ Data.Generics.Traversable.Zipper: transM :: Monad m => (forall d. Rec c d => d -> m d) -> Zipper c a -> m (Zipper c a)

Files

CHANGES.md view
@@ -1,6 +1,13 @@ Changes ======= +Version 1.0.0.0+---------------++Replace implicit parameters with explicit type application.++This drops support for GHCs older than 8.0.+ Version 0.2.0.4 --------------- 
Data/Generics/Traversable.hs view
@@ -1,28 +1,26 @@-{-# LANGUAGE ConstraintKinds, KindSignatures, MultiParamTypeClasses, RankNTypes, UndecidableInstances, ImplicitParams, ScopedTypeVariables, FlexibleContexts, FlexibleInstances, CPP #-}--#if __GLASGOW_HASKELL__ >= 800-{-# LANGUAGE UndecidableSuperClasses #-}-#endif- -- | All of the functions below work only on «interesting» subterms. -- It is up to the instance writer to decide which subterms are -- interesting and which subterms should count as immediate. This can -- also depend on the context @c@. -- -- The context, denoted @c@, is a constraint (of kind @* -> Constraint@)--- that provides additional facilities to work with the data. Most--- functions take an implicit parameter @?c :: p c@; it's--- used to disambugate which context you are referring to. @p@ can be--- @Proxy@ from the @tagged@ package or any other suitable type--- constructor.+-- that provides additional facilities to work with the data.+-- In most cases, the context cannot be inferred automatically.+-- You need to provide it using the+-- <https://downloads.haskell.org/~ghc/8.0.2/docs/html/users_guide/glasgow_exts.html#visible-type-application type application syntax>: --+-- > gmap @Show f x+-- > everywhere @Typeable f x+--+-- etc.+-- -- For more information, see: -- -- [Scrap your boilerplate with class]--- <http://research.microsoft.com/en-us/um/people/simonpj/papers/hmap/>+-- <https://www.microsoft.com/en-us/research/publication/scrap-your-boilerplate-with-class/> -- -- [Generalizing generic fold]--- <http://ro-che.info/articles/2013-03-11-generalizing-gfoldl.html>+-- <http://ro-che.info/articles/2013-03-11-generalizing-gfoldl>  module Data.Generics.Traversable   (@@ -51,15 +49,10 @@ import Data.Monoid import Data.Functor.Identity import Data.Functor.Constant-import Data.Proxy.Fork  import Data.Generics.Traversable.Core import Data.Generics.Traversable.Instances () --- for documentation only-import Data.Foldable-import Data.Traversable- -- | 'Rec' enables \"deep traversals\". -- -- It is satisfied automatically when its superclass constraints are@@ -69,90 +62,85 @@  -- | Generic map over the immediate subterms gmap-  :: (GTraversable c a, ?c :: p c)+  :: forall c a . (GTraversable c a)   => (forall d . (c d) => d -> d)   -> a -> a-gmap f = runIdentity . gtraverse (Identity . f)+gmap f a = runIdentity (gtraverse @c (Identity . f) a)  -- | Generic monadic map over the immediate subterms gmapM-  :: (Monad m, GTraversable c a, ?c :: p c)+  :: forall c m a . (Monad m, GTraversable c a)   => (forall d . (c d) => d -> m d)   -> a -> m a-gmapM f = unwrapMonad . gtraverse (WrapMonad . f)+gmapM f = unwrapMonad . gtraverse @c (WrapMonad . f) --- | Generic monoidal fold over the immediate subterms (cf. 'foldMap' from--- "Data.Foldable")+-- | Generic monoidal fold over the immediate subterms (cf. 'Data.Foldable.foldMap') gfoldMap-  :: (Monoid r, GTraversable c a, ?c :: p c)+  :: forall c r a . (Monoid r, GTraversable c a)   => (forall d . (c d) => d -> r)   -> a -> r-gfoldMap f = getConstant . gtraverse (Constant . f)+gfoldMap f = getConstant . gtraverse @c (Constant . f)  -- | Generic right fold over the immediate subterms gfoldr-  :: (GTraversable c a, ?c :: p c)+  :: forall c a r . (GTraversable c a)   => (forall d . (c d) => d -> r -> r)   -> r -> a -> r-gfoldr f z t = appEndo (gfoldMap (Endo . f) t) z+gfoldr f z t = appEndo (gfoldMap @c (Endo . f) t) z  -- | Generic strict left fold over the immediate subterms gfoldl'-  :: (GTraversable c a, ?c :: p c)+  :: forall c a r . (GTraversable c a)   => (forall d . (c d) => r -> d -> r)   -> r -> a -> r-gfoldl' f z0 xs = gfoldr f' id xs z0+gfoldl' f z0 xs = gfoldr @c f' id xs z0   where f' x k z = k $! f z x  -- | Apply a transformation everywhere in bottom-up manner everywhere-  :: forall a c p .-     (Rec c a, ?c :: p c)+  :: forall c a .+     (Rec c a)   => (forall d. (Rec c d) => d -> d)   -> a -> a everywhere f =-  let ?c = Proxy :: Proxy (Rec c) in   let-    go :: forall a . Rec c a => a -> a-    go = f . gmap go+    go :: forall b . Rec c b => b -> b+    go = f . gmap @(Rec c) go   in go  -- | Apply a transformation everywhere in top-down manner everywhere'-  :: forall a c p .-     (Rec c a, ?c :: p c)+  :: forall c a .+     (Rec c a)   => (forall d. (Rec c d) => d -> d)   -> a -> a everywhere' f =-  let ?c = Proxy :: Proxy (Rec c) in   let-    go :: forall a . Rec c a => a -> a-    go = gmap go . f+    go :: forall b . Rec c b => b -> b+    go = gmap @(Rec c) go . f   in go  -- | Monadic variation on everywhere everywhereM-  :: forall m a c p .-     (Monad m, Rec c a, ?c :: p c)+  :: forall c m a .+     (Monad m, Rec c a)   => (forall d. (Rec c d) => d -> m d)   -> a -> m a everywhereM f =-  let ?c = Proxy :: Proxy (Rec c) in   let-    go :: forall a . Rec c a => a -> m a-    go = f <=< gmapM go+    go :: forall b . Rec c b => b -> m b+    go = f <=< gmapM @(Rec c) go   in go  -- | Strict left fold over all elements, top-down everything-  :: forall r a c p .-     (Rec c a, ?c :: p c)+  :: forall c r a .+     (Rec c a)   => (r -> r -> r)   -> (forall d . (Rec c d) => d -> r)   -> a -> r everything combine f =-  let ?c = Proxy :: Proxy (Rec c) in   let-    go :: forall a . Rec c a => a -> r-    go x = gfoldl' (\a y -> combine a (go y)) (f x) x+    go :: forall b . Rec c b => b -> r+    go x = gfoldl' @(Rec c) (\a y -> combine a (go y)) (f x) x   in go
Data/Generics/Traversable/Core.hs view
@@ -1,22 +1,20 @@-{-# LANGUAGE ConstraintKinds, KindSignatures, MultiParamTypeClasses, RankNTypes, UndecidableInstances, ImplicitParams #-} module Data.Generics.Traversable.Core where  import GHC.Exts (Constraint)-import Control.Applicative  class GTraversable (c :: * -> Constraint) a where   -- | Applicative traversal over (a subset of) immediate subterms. This is-  -- a generic version of 'traverse' from "Data.Traversable".+  -- a generic version of 'Data.Traversable.traverse'.   --   -- The supplied function is applied only to the «interesting» subterms.   --   -- Other subterms are lifted using 'pure', and the whole structure is-  -- folded back using '<*>'.+  -- folded back using 'Control.Applicative.<*>'.   --   -- 'gtraverse' has a default implementation @const pure@, which works for   -- types without interesting subterms (in particular, atomic types).   gtraverse-    :: (Applicative f, ?c :: p c)+    :: (Applicative f)     => (forall d . c d => d -> f d)     -> a -> f a   gtraverse _ x = pure x
Data/Generics/Traversable/Instances.hs view
@@ -1,11 +1,11 @@-{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FlexibleInstances, ConstraintKinds, UndecidableInstances #-}+{-# LANGUAGE TemplateHaskell #-}+{-# OPTIONS_GHC -Wno-orphans #-} -- | This module defines 'GTraversable' instances for standard types -- exported by "Prelude" module Data.Generics.Traversable.Instances () where  import Data.Generics.Traversable.Core import Data.Generics.Traversable.TH-import Control.Applicative import Data.Ratio  instance GTraversable c ()
Data/Generics/Traversable/TH.hs view
@@ -11,18 +11,19 @@ import Language.Haskell.TH import Control.Monad import Data.Generics.Traversable.Core-import Control.Applicative import Data.List +err :: String -> a err s = error $ "Data.Generics.Traversable.TH: " ++ s +getDataInfo :: Name -> Q (Name, [Name], [(Name, Int, [Type])]) getDataInfo name = do   info <- reify name   let     decl =       case info of         TyConI d -> d-        _ -> error ("can't be used on anything but a type constructor of an algebraic data type")+        _ -> err "can't be used on anything but a type constructor of an algebraic data type"    return $     case decl of@@ -39,7 +40,7 @@ -- data type. gtraverseExpr :: Name -> Q Exp gtraverseExpr typeName = do-  (typeName, typeParams, constructors) <- getDataInfo typeName+  (_name, _params, constructors) <- getDataInfo typeName   f <- newName "f"   x <- newName "x" @@ -76,7 +77,6 @@ -- >  gtraverse = $(gtraverseExpr ''MyType) deriveGTraversable :: Name -> Q [Dec] deriveGTraversable name = do-  info <- reify name   ctx <- newName "c"    (typeName, typeParams, constructors) <- getDataInfo name@@ -104,9 +104,13 @@    sequence [inst] +conA :: Con -> (Name, Int, [Type]) conA (NormalC c xs)   = (c, length xs, map snd xs) conA (InfixC x1 c x2) = conA (NormalC c [x1, x2]) conA (ForallC _ _ c)  = conA c conA (RecC c xs)      = (c, length xs, map (\(_,_,t)->t) xs)+conA _ = err "GADTs are not supported yet"++varName :: TyVarBndr -> Name varName (PlainTV n) = n varName (KindedTV n _) = n
Data/Generics/Traversable/Zipper.hs view
@@ -60,9 +60,7 @@ -- Just 'd' -- -- So, unlike in @syz@, all of the list elements are siblings.-{-# LANGUAGE Rank2Types, GADTs, KindSignatures, ImplicitParams,-             ScopedTypeVariables, ConstraintKinds,-             MultiParamTypeClasses, UndecidableInstances #-}+{-# LANGUAGE GADTs #-}  module Data.Generics.Traversable.Zipper (   -- * Core types@@ -90,13 +88,10 @@   setHole'   ) where -import Control.Monad ((<=<), MonadPlus, mzero, mplus, liftM)-import Data.Maybe (fromJust)+import Control.Monad (liftM) import Data.Generics.Traversable import Data.Typeable (Typeable, cast)-import Data.Proxy.Fork import GHC.Exts (Constraint)-import Control.Applicative  -- Core types @@ -143,9 +138,7 @@ unit = LeftCons (LeftUnit id)  toLeft :: forall a c . (Rec c a) => a -> Left c a-toLeft =-  let ?c = Proxy :: Proxy (Rec c) in-    gtraverse unit+toLeft = gtraverse @(Rec c) unit  fromLeft :: Left c r -> r fromLeft (LeftUnit a)   = a@@ -212,20 +205,20 @@  -- | Apply a generic query to the hole. query-  :: (forall a . Rec c a => a -> b)+  :: (forall d . Rec c d => d -> b)   -> Zipper c a -> b query f (Zipper hole _ctxt) = f hole  -- | Apply a generic transformation to the hole. trans-  :: (forall a . Rec c a => a -> a)+  :: (forall d . Rec c d => d -> d)   -> Zipper c a -> Zipper c a trans f (Zipper hole ctxt) = Zipper (f hole) ctxt  -- | Apply a generic monadic transformation to the hole transM   :: Monad m-  => (forall a . Rec c a => a -> m a)+  => (forall d . Rec c d => d -> m d)   -> Zipper c a -> m (Zipper c a) transM f (Zipper hole ctxt) = do   hole' <- f hole
− Data/Proxy/Fork.hs
@@ -1,8 +0,0 @@-{-# LANGUAGE ConstraintKinds, KindSignatures, PolyKinds #-}--- | In @tagged@, PolyKinds are enabled only starting with 7.6. Hence we--- have our own Proxy.-module Data.Proxy.Fork where--import GHC.Exts (Constraint)--data Proxy (c :: * -> Constraint) = Proxy
+ tests/test.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FlexibleInstances, ConstraintKinds, UndecidableInstances #-}+{-# LANGUAGE TypeApplications #-}+import Test.Tasty+import Test.Tasty.HUnit+import Data.Generics.Traversable+import Data.Generics.Traversable.Zipper+import Data.Generics.Traversable.TH++data User a = User+ { name :: String+ , age  :: Int+ , misc :: a+ } deriving Show++alice :: User (Bool, Int)+alice = User "Alice" 22 (True, 12)++deriveGTraversable ''User++class U a+instance U a++main = defaultMain $ testGroup "Tests"+  [ testCase "size via gfoldl'" $+      gfoldl' @U (\a x -> a+1) 0 alice @?= 3+  , testCase "show immediate children via gfoldMap" $+      gfoldMap @Show (pure . show) alice @?= ["\"Alice\"","22","(True,12)"]+  , testCase "show all children via everything" $+      -- don't copy-paste this code; it's quadratic!+      everything @Show (++) (pure . show) alice @?=+        ["User {name = \"Alice\", age = 22, misc = (True,12)}","\"Alice\"","'A'","'l'","'i'","'c'","'e'","22","(True,12)","True","12"]+  , testCase "A zipper walk" $ do+      let z0 = toZipper @Show alice+      let Just z1 = down' z0 -- down' moves to the leftmost child+      query show z1 @?= "\"Alice\""+      let Just z2 = right z1+      query show z2 @?= "22"+      let Just z3 = down =<< right z2 -- down moves to the rightmost child+      query show z3 @?= "12"+      let Just z4 = left z3 -- down moves to the rightmost child+      query show z4 @?= "True"+  ]
traverse-with-class.cabal view
@@ -1,8 +1,8 @@--- Initial traverse-with-class.cabal generated by cabal init.  For further +-- Initial traverse-with-class.cabal generated by cabal init.  For further -- documentation, see http://haskell.org/cabal/users-guide/  name:                traverse-with-class-version:             0.2.0.4+version:             1.0.0.0 synopsis:            Generic applicative traversals description:         This is a generic programming library in the spirit of                      \"Scrap your boilerplate with class\", but with several@@ -15,7 +15,6 @@ license-file:        LICENSE author:              Roman Cheplyaka maintainer:          Roman Cheplyaka <roma@ro-che.info>--- copyright:            category:            Data build-type:          Simple cabal-version:       >=1.10@@ -23,6 +22,10 @@   README.md   CHANGES.md +source-repository head+  type:     git+  location: https://github.com/feuerbach/traverse-with-class.git+ library   exposed-modules:     Data.Generics.Traversable                        Data.Generics.Traversable.TH@@ -30,7 +33,39 @@   other-modules:                        Data.Generics.Traversable.Core                        Data.Generics.Traversable.Instances-                       Data.Proxy.Fork-  build-depends:       base == 4.*, transformers, template-haskell+  build-depends:+                       -- we rely on TypeApplications and therefore only support GHC 8++                       -- you can use older versions of this package with older GHCs+                       base >= 4.9 && < 5,+                       transformers,+                       template-haskell   default-language:    Haskell2010+  default-extensions:  ConstraintKinds+                       KindSignatures+                       MultiParamTypeClasses+                       RankNTypes+                       UndecidableInstances+                       ScopedTypeVariables+                       FlexibleContexts+                       FlexibleInstances+                       TypeApplications+                       AllowAmbiguousTypes+                       UndecidableSuperClasses   other-extensions:    TemplateHaskell+  ghc-options:         -Wall+++test-suite test+  default-language:+    Haskell2010+  type:+    exitcode-stdio-1.0+  hs-source-dirs:+    tests+  main-is:+    test.hs+  build-depends:+      base+    , tasty >= 0.7+    , tasty-hunit+    , traverse-with-class