rank2classes 0.2.1.1 → 1.0
raw patch · 3 files changed
+42/−35 lines, 3 files
Files
- rank2classes.cabal +4/−4
- src/Rank2.hs +34/−27
- src/Rank2/TH.hs +4/−4
rank2classes.cabal view
@@ -1,9 +1,9 @@ name: rank2classes-version: 0.2.1.1-synopsis: a mirror image of some standard type classes, with methods of rank 2 types+version: 1.0+synopsis: standard type constructor class hierarchy, only with methods of rank 2 types description:- A mirror image of the standard constructor type class hierarchy rooted in 'Functor', except with methods of rank 2- types and class instances of kind @(*->*)->*@. The classes enable generic handling of heterogenously typed data+ A mirror image of the standard type constructor class hierarchy rooted in 'Functor', except with methods of rank 2+ types and class instances of kind @(k->*)->*@. The classes enable generic handling of heterogenously typed data structures and other neat tricks. homepage: https://github.com/blamario/grampa/tree/master/rank2classes
src/Rank2.hs view
@@ -15,7 +15,7 @@ -- * Method synonyms and helper functions ap, fmap, liftA4, liftA5, fmapTraverse, liftA2Traverse1, liftA2Traverse2, liftA2TraverseBoth,- cotraverse, cotraverseTraversable)+ distributeWith, distributeWithTraversable) where import qualified Control.Applicative as Rank1@@ -27,7 +27,10 @@ import Prelude hiding (Foldable(..), Traversable(..), Functor(..), Applicative(..), (<$>), fst, snd) --- | Equivalent of 'Functor' for rank 2 data types+-- | Equivalent of 'Functor' for rank 2 data types, satisfying the usual functor laws+--+-- > id <$> g == g+-- > (p . q) <$> g == p <$> (q <$> g) class Functor g where (<$>) :: (forall a. p a -> q a) -> g p -> g q @@ -51,7 +54,7 @@ -- | Wrapper for functions that map the argument constructor type newtype Arrow p q a = Arrow{apply :: p a -> q a} --- | Subclass of 'Functor' halfway to 'Applicative'+-- | Subclass of 'Functor' halfway to 'Applicative', satisfying -- -- > (.) <$> u <*> v <*> w == u <*> (v <*> w) class Functor g => Apply g where@@ -80,33 +83,35 @@ -- | Equivalent of 'Rank1.Applicative' for rank 2 data types class Apply g => Applicative g where pure :: (forall a. f a) -> g f- + -- | Equivalent of 'Rank1.Distributive' for rank 2 data types class DistributiveTraversable g => Distributive g where- {-# MINIMAL distributeWith #-}+ {-# MINIMAL cotraverse|distribute #-} collect :: Rank1.Functor f1 => (a -> g f2) -> f1 a -> g (Compose f1 f2) distribute :: Rank1.Functor f1 => f1 (g f2) -> g (Compose f1 f2)- distributeWith :: Rank1.Functor f1 => (forall x. f1 (f2 x) -> f x) -> f1 (g f2) -> g f+ -- | Dual of 'traverse', equivalent of 'Rank1.cotraverse' for rank 2 data types + cotraverse :: Rank1.Functor m => (forall a. m (p a) -> q a) -> m (g p) -> g q collect f = distribute . Rank1.fmap f- distribute = distributeWith Compose+ distribute = cotraverse Compose+ cotraverse f = (fmap (f . getCompose)) . distribute -- | A weaker 'Distributive' that requires 'Rank1.Traversable' to use, not just a 'Rank1.Functor'. class Functor g => DistributiveTraversable (g :: (k -> *) -> *) where collectTraversable :: Rank1.Traversable f1 => (a -> g f2) -> f1 a -> g (Compose f1 f2) distributeTraversable :: Rank1.Traversable f1 => f1 (g f2) -> g (Compose f1 f2)- distributeWithTraversable :: Rank1.Traversable f1 => (forall x. f1 (f2 x) -> f x) -> f1 (g f2) -> g f+ cotraverseTraversable :: Rank1.Traversable f1 => (forall x. f1 (f2 x) -> f x) -> f1 (g f2) -> g f collectTraversable f = distributeTraversable . Rank1.fmap f- distributeTraversable = distributeWithTraversable Compose+ distributeTraversable = cotraverseTraversable Compose - default distributeWithTraversable :: (Rank1.Traversable f1, Distributive g) => - (forall x. f1 (f2 x) -> f x) -> f1 (g f2) -> g f- distributeWithTraversable = distributeWith+ default cotraverseTraversable :: (Rank1.Traversable m, Distributive g) => + (forall a. m (p a) -> q a) -> m (g p) -> g q+ cotraverseTraversable = cotraverse -- | A variant of 'distribute' convenient with 'Rank1.Monad' instances distributeJoin :: (Distributive g, Rank1.Monad f) => f (g f) -> g f-distributeJoin = distributeWith Rank1.join+distributeJoin = cotraverse Rank1.join -- | Like 'fmap', but traverses over its argument fmapTraverse :: (DistributiveTraversable f, Rank1.Traversable g) => (forall a. g (t a) -> u a) -> g (f t) -> f u@@ -128,14 +133,16 @@ liftA2TraverseBoth f x y = liftA2 applyCompose (distributeTraversable x) (distributeTraversable y) where applyCompose x' y' = f (getCompose x') (getCompose y') --- | Equivalent of 'Rank1.cotraverse' for rank 2 data types -cotraverse :: (Distributive g, Rank1.Functor f) => (forall i. f (a i) -> b i) -> f (g a) -> g b-cotraverse f = (fmap (f . getCompose)) . distribute+{-# DEPRECATED distributeWith "Use cotraverse instead." #-}+-- | Synonym for 'cotraverse'+distributeWith :: (Distributive g, Rank1.Functor f) => (forall i. f (a i) -> b i) -> f (g a) -> g b+distributeWith = cotraverse --- | Equivalent of 'Rank1.cotraverse' for rank 2 data types using traversable-cotraverseTraversable :: (DistributiveTraversable g, Rank1.Traversable f) => - (forall i. f (a i) -> b i) -> f (g a) -> g b-cotraverseTraversable f = (fmap (f . getCompose)) . distributeTraversable+{-# DEPRECATED distributeWithTraversable "Use cotraverseTraversable instead." #-}+-- | Synonym for 'cotraverseTraversable'+distributeWithTraversable :: (DistributiveTraversable g, Rank1.Traversable m) =>+ (forall a. m (p a) -> q a) -> m (g p) -> g q+distributeWithTraversable = cotraverseTraversable -- | A rank-2 equivalent of '()', a zero-element tuple data Empty f = Empty deriving (Eq, Ord, Show)@@ -238,20 +245,20 @@ instance DistributiveTraversable Empty instance DistributiveTraversable (Only x) instance DistributiveTraversable g => DistributiveTraversable (Identity g) where- distributeWithTraversable w f = Identity (distributeWithTraversable w $ Rank1.fmap runIdentity f)+ cotraverseTraversable w f = Identity (cotraverseTraversable w $ Rank1.fmap runIdentity f) instance (DistributiveTraversable g, DistributiveTraversable h) => DistributiveTraversable (Product g h) where- distributeWithTraversable w f = Pair (distributeWithTraversable w $ Rank1.fmap fst f) - (distributeWithTraversable w $ Rank1.fmap snd f)+ cotraverseTraversable w f = Pair (cotraverseTraversable w $ Rank1.fmap fst f) + (cotraverseTraversable w $ Rank1.fmap snd f) instance Distributive Empty where- distributeWith _ _ = Empty+ cotraverse _ _ = Empty instance Distributive (Only x) where- distributeWith w f = Only (w $ Rank1.fmap fromOnly f)+ cotraverse w f = Only (w $ Rank1.fmap fromOnly f) instance Distributive g => Distributive (Identity g) where- distributeWith w f = Identity (distributeWith w $ Rank1.fmap runIdentity f)+ cotraverse w f = Identity (cotraverse w $ Rank1.fmap runIdentity f) instance (Distributive g, Distributive h) => Distributive (Product g h) where- distributeWith w f = Pair (distributeWith w $ Rank1.fmap fst f) (distributeWith w $ Rank1.fmap snd f)+ cotraverse w f = Pair (cotraverse w $ Rank1.fmap fst f) (cotraverse w $ Rank1.fmap snd f)
src/Rank2/TH.hs view
@@ -101,10 +101,10 @@ genTraverse cs = funD 'Rank2.traverse (map genTraverseClause cs) genDistributeWith :: [Con] -> Q Dec-genDistributeWith cs = funD 'Rank2.distributeWith (map genDistributeWithClause cs)+genDistributeWith cs = funD 'Rank2.cotraverse (map genDistributeWithClause cs) genDistributeWithTraversable :: [Con] -> Q Dec-genDistributeWithTraversable cs = funD 'Rank2.distributeWith (map genDistributeWithTraversableClause cs)+genDistributeWithTraversable cs = funD 'Rank2.cotraverse (map genDistributeWithTraversableClause cs) genFmapClause :: Con -> Q Clause genFmapClause (NormalC name fieldTypes) = do@@ -324,7 +324,7 @@ | ty == VarT typeVar -> fieldExp fieldName [| $(varE withName) ($(varE fieldName) <$> $(varE argName)) |] AppT _ ty | ty == VarT typeVar ->- fieldExp fieldName [| Rank2.distributeWith $(varE withName) ($(varE fieldName) <$> $(varE argName)) |]+ fieldExp fieldName [| Rank2.cotraverse $(varE withName) ($(varE fieldName) <$> $(varE argName)) |] clause [varP withName, varP argName] body [] genDistributeWithTraversableClause :: Con -> Q Clause@@ -340,5 +340,5 @@ | ty == VarT typeVar -> fieldExp fieldName [| $(varE withName) ($(varE fieldName) <$> $(varE argName)) |] AppT _ ty | ty == VarT typeVar ->- fieldExp fieldName [| Rank2.distributeWithTraversable $(varE withName) ($(varE fieldName) <$> $(varE argName)) |]+ fieldExp fieldName [| Rank2.cotraverseTraversable $(varE withName) ($(varE fieldName) <$> $(varE argName)) |] clause [varP withName, varP argName] body []