packages feed

newtype-generics 0.5.2.2 → 0.5.3

raw patch · 7 files changed

+397/−411 lines, 7 filesdep −HUnitdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies removed: HUnit

Dependency ranges changed: base

API changes (from Hackage documentation)

- Control.Newtype: ala :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> ((o -> n) -> b -> n') -> (b -> o')
- Control.Newtype: ala' :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> (b -> o')
- Control.Newtype: class Newtype n where {
- Control.Newtype: instance Control.Newtype.GNewtype (GHC.Generics.D1 d (GHC.Generics.C1 c (GHC.Generics.S1 s (GHC.Generics.K1 i a))))
- Control.Newtype: instance Control.Newtype.Newtype (Control.Applicative.WrappedArrow a b c)
- Control.Newtype: instance Control.Newtype.Newtype (Control.Applicative.WrappedMonad m a)
- Control.Newtype: instance Control.Newtype.Newtype (Control.Applicative.ZipList a)
- Control.Newtype: instance Control.Newtype.Newtype (Control.Arrow.ArrowMonad a b)
- Control.Newtype: instance Control.Newtype.Newtype (Control.Arrow.Kleisli m a b)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Fixed.Fixed a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Functor.Compose.Compose f g a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Functor.Const.Const a x)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Functor.Identity.Identity a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Monoid.Alt f a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Monoid.Dual a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Monoid.Endo a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Monoid.First a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Monoid.Last a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Monoid.Product a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Monoid.Sum a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Ord.Down a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Semigroup.First a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Semigroup.Last a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Semigroup.Max a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Semigroup.Min a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Semigroup.Option a)
- Control.Newtype: instance Control.Newtype.Newtype (Data.Semigroup.WrappedMonoid m)
- Control.Newtype: instance Control.Newtype.Newtype Data.Monoid.All
- Control.Newtype: instance Control.Newtype.Newtype Data.Monoid.Any
- Control.Newtype: op :: (Newtype n, o ~ O n) => (o -> n) -> n -> o
- Control.Newtype: over :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (o -> o') -> (n -> n')
- Control.Newtype: over2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (o -> o -> o') -> (n -> n -> n')
- Control.Newtype: overF :: (Newtype n, Newtype n', o' ~ O n', o ~ O n, Functor f, Functor g) => (o -> n) -> (f o -> g o') -> (f n -> g n')
- Control.Newtype: pack :: (Newtype n, Generic n, GNewtype (Rep n), O n ~ GO (Rep n)) => O n -> n
- Control.Newtype: type O n = GO (Rep n);
- Control.Newtype: type family O n :: *;
- Control.Newtype: under :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (n -> n') -> (o -> o')
- Control.Newtype: under2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (n -> n -> n') -> (o -> o -> o')
- Control.Newtype: underF :: (Newtype n, Newtype n', o' ~ O n', o ~ O n, Functor f, Functor g) => (o -> n) -> (f n -> g n') -> (f o -> g o')
- Control.Newtype: unpack :: (Newtype n, Generic n, GNewtype (Rep n), O n ~ GO (Rep n)) => n -> O n
- Control.Newtype: }
+ Control.Newtype.Generics: ala :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> ((o -> n) -> b -> n') -> (b -> o')
+ Control.Newtype.Generics: ala' :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> (b -> o')
+ Control.Newtype.Generics: class Newtype n where {
+ Control.Newtype.Generics: instance Control.Newtype.Generics.GNewtype (GHC.Generics.D1 d (GHC.Generics.C1 c (GHC.Generics.S1 s (GHC.Generics.K1 i a))))
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Control.Applicative.WrappedArrow a b c)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Control.Applicative.WrappedMonad m a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Control.Applicative.ZipList a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Control.Arrow.ArrowMonad a b)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Control.Arrow.Kleisli m a b)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Fixed.Fixed a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Functor.Compose.Compose f g a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Functor.Const.Const a x)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Functor.Identity.Identity a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Monoid.Alt f a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Monoid.Dual a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Monoid.Endo a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Monoid.First a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Monoid.Last a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Monoid.Product a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Monoid.Sum a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Ord.Down a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Semigroup.First a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Semigroup.Last a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Semigroup.Max a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Semigroup.Min a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Semigroup.Option a)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype (Data.Semigroup.WrappedMonoid m)
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype Data.Monoid.All
+ Control.Newtype.Generics: instance Control.Newtype.Generics.Newtype Data.Monoid.Any
+ Control.Newtype.Generics: op :: (Newtype n, o ~ O n) => (o -> n) -> n -> o
+ Control.Newtype.Generics: over :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (o -> o') -> (n -> n')
+ Control.Newtype.Generics: over2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (o -> o -> o') -> (n -> n -> n')
+ Control.Newtype.Generics: overF :: (Newtype n, Newtype n', o' ~ O n', o ~ O n, Functor f, Functor g) => (o -> n) -> (f o -> g o') -> (f n -> g n')
+ Control.Newtype.Generics: pack :: (Newtype n, Generic n, GNewtype (Rep n), O n ~ GO (Rep n)) => O n -> n
+ Control.Newtype.Generics: type O n = GO (Rep n);
+ Control.Newtype.Generics: type family O n :: *;
+ Control.Newtype.Generics: under :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (n -> n') -> (o -> o')
+ Control.Newtype.Generics: under2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (n -> n -> n') -> (o -> o -> o')
+ Control.Newtype.Generics: underF :: (Newtype n, Newtype n', o' ~ O n', o ~ O n, Functor f, Functor g) => (o -> n) -> (f n -> g n') -> (f o -> g o')
+ Control.Newtype.Generics: unpack :: (Newtype n, Generic n, GNewtype (Rep n), O n ~ GO (Rep n)) => n -> O n
+ Control.Newtype.Generics: }

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Changelog for `newtype-generics` +## [0.5.3] – 2018-03-23+- All code was moved to a new `Control.Newtype.Generics` module.+- `Control.Newtype` re-exports `Control.Newtype.Generics`, but is deprecated+  and will be removed in the next major release.+ ## [0.5.2.2] – 2018-03-16 - Adjust bounds for `base` and `transformers` @@ -27,7 +32,8 @@ - Relax types of `underF` and `overF` to allow different input & output functors  -[Unreleased]: https://github.com/jcristovao/newtype-generics/compare/v0.5.2.2...HEAD+[Unreleased]: https://github.com/jcristovao/newtype-generics/compare/v0.5.3...HEAD+[0.5.3]: https://github.com/jcristovao/newtype-generics/compare/v0.5.2.2...v0.5.3 [0.5.2.2]: https://github.com/jcristovao/newtype-generics/compare/v0.5.2.1...v0.5.2.2 [0.5.2.1]: https://github.com/jcristovao/newtype-generics/compare/v0.5.2...v0.5.2.1 [0.5.2]: https://github.com/jcristovao/newtype-generics/compare/v0.5.1...v0.5.2
Control/Newtype.hs view
@@ -1,372 +1,6 @@-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeFamilies #-}-{-# LANGUAGE CPP                        #-}-{-# LANGUAGE DeriveGeneric              #-}-{-# LANGUAGE DefaultSignatures          #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# LANGUAGE StandaloneDeriving         #-}-{-# LANGUAGE UndecidableInstances       #-}-{- |-The 'Newtype' typeclass and related functions.-Primarily pulled from Conor McBride's Epigram work. Some examples:-->>> ala Sum foldMap [1,2,3,4]-10-->>> ala Endo foldMap [(+1), (+2), (subtract 1), (*2)] 3-8-->>> under2 Min (<>) 2 1-1-->>> over All not (All False)-All {getAll = True)--This package includes 'Newtype' instances for all the (non-GHC\/foreign)-newtypes in base (as seen in the examples).-However, there are neat things you can do with this with-/any/ newtype and you should definitely define your own 'Newtype'-instances for the power of this library.-For example, see @ala Cont traverse@, with the proper 'Newtype' instance for Cont.-You can easily define new instances for your newtypes with the help of GHC.Generics-- > {-# LANGUAGE DeriveGeneric #-}- > import GHC.Generics- >- > (...)- > newtype Example = Example Int - >   deriving (Generic)- >- > instance Newtype Example- >--This avoids the use of Template Haskell (TH) to get new instances.--} module Control.Newtype-  ( Newtype(..)-  , op-  , ala-  , ala'-  , under-  , over-  , under2-  , over2-  , underF-  , overF+{-# deprecated "Import \"Control.Newtype.Generics\" instead" #-}+  ( module Control.Newtype.Generics   ) where -import Control.Applicative-import Control.Arrow-import Data.Functor.Compose-import Data.Functor.Identity-#if MIN_VERSION_base(4,7,0)-import Data.Fixed-#endif-import Data.Monoid-import Data.Ord-#if MIN_VERSION_base(4,9,0)-import qualified Data.Semigroup-import Data.Semigroup (Min(..), Max(..), WrappedMonoid(..), Option(..))-#endif-import GHC.Generics-{-import Generics.Deriving-}---- | Given a newtype @n@, we will always have the same unwrapped type @o@,--- meaning we can represent this with a fundep @n -> o@.------ Any instance of this class just needs to let @pack@ equal to the newtype's--- constructor, and let @unpack@ destruct the newtype with pattern matching.-{-class Newtype n o | n -> o where-}-  {-pack :: o -> n-}-  {-unpack :: n -> o-}----- Generic Newtype-class GNewtype n where-  type GO n :: *-  gpack   :: GO n -> n p-  gunpack :: n p  -> GO n---- We only need one instance, if these generic functions are only to work for--- newtypes, as these have a fixed form. For example, for a newtype X = Y,--- Rep X = D1 ... (C1 ... (S1 ... (K1 ... Y)))-instance GNewtype (D1 d (C1 c (S1 s (K1 i a)))) where-  type GO (D1 d (C1 c (S1 s (K1 i a)))) = a-  gpack   x                     = M1 (M1 (M1 (K1 x)))-  gunpack (M1 (M1 (M1 (K1 x)))) = x---- Original Newtype class, extended with generic defaults (trivial) and deprived--- of the second type argument (less trivial, as it involves a type family with--- a default, plus an equality constraint for the related type family in--- GNewtype). We do get rid of MultiParamTypeClasses and FunctionalDependencies,--- though.---- | As long as the type @n@ is an instance of Generic, you can create an instance--- with just @instance Newtype n@-class Newtype n where-  type O n :: *-  type O n = GO (Rep n)--  pack   :: O n -> n-  default pack :: (Generic n, GNewtype (Rep n), O n ~ GO (Rep n)) => O n -> n-  pack = to . gpack--  unpack :: n -> O n-  default unpack :: (Generic n, GNewtype (Rep n), O n ~ GO (Rep n)) => n -> O n-  unpack = gunpack . from---- |--- This function serves two purposes:------ 1. Giving you the unpack of a newtype without you needing to remember the name.------ 2. Showing that the first parameter is /completely ignored/ on the value level,---    meaning the only reason you pass in the constructor is to provide type---    information.  Typeclasses sure are neat.------ >>> op Identity (Identity 3)--- 3-op :: (Newtype n,o ~ O n ) => (o -> n) -> n -> o-op _ = unpack---- | The workhorse of the package. Given a "packer" and a \"higher order function\" (/hof/),--- it handles the packing and unpacking, and just sends you back a regular old--- function, with the type varying based on the /hof/ you passed.------ The reason for the signature of the /hof/ is due to 'ala' not caring about structure.--- To illustrate why this is important, consider this alternative implementation of 'under2':------ > under2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)--- >        => (o -> n) -> (n -> n -> n') -> (o -> o -> o')--- > under2' pa f o0 o1 = ala pa (\p -> uncurry f . bimap p p) (o0, o1)------ Being handed the "packer", the /hof/ may apply it in any structure of its choosing –--- in this case a tuple.------ >>> ala Sum foldMap [1,2,3,4]--- 10-ala :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)-    => (o -> n) -> ((o -> n) -> b -> n') -> (b -> o')-ala pa hof = ala' pa hof id---- | This is the original function seen in Conor McBride's work.--- The way it differs from the 'ala' function in this package,--- is that it provides an extra hook into the \"packer\" passed to the hof.--- However, this normally ends up being @id@, so 'ala' wraps this function and--- passes @id@ as the final parameter by default.--- If you want the convenience of being able to hook right into the hof,--- you may use this function.------ >>> ala' Sum foldMap length ["hello", "world"]--- 10------ >>> ala' First foldMap (readMaybe @Int) ["x", "42", "1"]--- Just 42-ala' :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)-     => (o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> (b -> o')-ala' _ hof f = unpack . hof (pack . f)---- | A very simple operation involving running the function \'under\' the newtype.------ >>> under Product (stimes 3) 3--- 27-under :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)-      => (o -> n) -> (n -> n') -> (o -> o')-under _ f = unpack . f . pack---- | The opposite of 'under'. I.e., take a function which works on the--- underlying types, and switch it to a function that works on the newtypes.------ >>> over All not (All False)--- All {getAll = True}-over :: (Newtype n,  Newtype n', o' ~ O n', o ~ O n)-     => (o -> n) -> (o -> o') -> (n -> n')-over _ f = pack . f . unpack---- | Lower a binary function to operate on the underlying values.------ >>> under2 Any (<>) True False--- True------ @since 0.5.2-under2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)-       => (o -> n) -> (n -> n -> n') -> (o -> o -> o')-under2 _ f o0 o1 = unpack $ f (pack o0) (pack o1)---- | The opposite of 'under2'.------ @since 0.5.2-over2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)-       => (o -> n) -> (o -> o -> o') -> (n -> n -> n')-over2 _ f n0 n1 = pack $ f (unpack n0) (unpack n1)---- | 'under' lifted into a Functor.-underF :: (Newtype n, Newtype n', o' ~ O n', o ~ O n, Functor f, Functor g)-       => (o -> n) -> (f n -> g n') -> (f o -> g o')-underF _ f = fmap unpack . f . fmap pack---- | 'over' lifted into a Functor.-overF :: (Newtype n, Newtype n', o' ~ O n', o ~ O n, Functor f, Functor g)-      => (o -> n) -> (f o -> g o') -> (f n -> g n')-overF _ f = fmap pack . f . fmap unpack---- Instances from Control.Applicative--instance Newtype (WrappedMonad m a) where-  type O (WrappedMonad m a) = m a-  pack = WrapMonad-  unpack (WrapMonad a) = a--instance Newtype (WrappedArrow a b c) where-  type O (WrappedArrow a b c) = a b c-  pack = WrapArrow-  unpack (WrapArrow a) = a--instance Newtype (ZipList a) where-  type O (ZipList a) = [a]-  pack = ZipList-  unpack (ZipList a) = a---- Instances from Control.Arrow--instance Newtype (Kleisli m a b) where-  type O (Kleisli m a b) = a -> m b-  pack = Kleisli-  unpack (Kleisli a) = a--instance Newtype (ArrowMonad a b) where-  type O (ArrowMonad a b) = a () b-  pack = ArrowMonad-  unpack (ArrowMonad a) = a--#if MIN_VERSION_base(4,7,0)--- Instances from Data.Fixed---- | @since 0.5.1-instance Newtype (Fixed a) where-  type O (Fixed a) = Integer-  pack = MkFixed-  unpack (MkFixed x) = x-#endif---- Instances from Data.Functor.Compose---- | @since 0.5.1-instance Newtype (Compose f g a) where-  type O (Compose f g a) = f (g a)-  pack = Compose-  unpack (Compose x) = x---- Instances from Data.Functor.Const--instance Newtype (Const a x) where-  type O (Const a x) = a-  pack = Const-  unpack (Const a) = a---- Instances from Data.Functor.Identity---- | @since 0.5.1-instance Newtype (Identity a) where-  type O (Identity a) = a-  pack = Identity-  unpack (Identity a) = a---- Instances from Data.Monoid---- | @since 0.5.1-instance Newtype (Dual a) where-  type O (Dual a) = a-  pack = Dual-  unpack (Dual a) = a--instance Newtype (Endo a) where-  type O (Endo a) = (a -> a)-  pack = Endo-  unpack (Endo a) = a--instance Newtype All where-  type O All = Bool-  pack = All-  unpack (All x) = x--instance Newtype Any where-  type O Any = Bool-  pack = Any-  unpack (Any x) = x--instance Newtype (Sum a) where-  type O (Sum a) = a-  pack = Sum-  unpack (Sum a) = a--instance Newtype (Product a) where-  type O (Product a) = a-  pack = Product-  unpack (Product a) = a--instance Newtype (First a) where-  type O (First a) = Maybe a-  pack = First-  unpack (First a) = a--instance Newtype (Last a) where-  type O (Last a) = Maybe a-  pack = Last-  unpack (Last a) = a--#if MIN_VERSION_base(4,8,0)--- | @since 0.5.1-instance Newtype (Alt f a) where-  type O (Alt f a) = f a-  pack = Alt-  unpack (Alt x) = x-#endif---- Instances from Data.Ord---- | @since 0.5.1-instance Newtype (Down a) where-  type O (Down a) = a-  pack = Down-  unpack (Down a) = a---#if MIN_VERSION_base(4,9,0)--- Instances from Data.Semigroup---- | @since 0.5.1-instance Newtype (Min a) where-  type O (Min a) = a-  pack = Min-  unpack (Min a) = a---- | @since 0.5.1-instance Newtype (Max a) where-  type O (Max a) = a-  pack = Max-  unpack (Max a) = a---- | @since 0.5.1-instance Newtype (Data.Semigroup.First a) where-  type O (Data.Semigroup.First a) = a-  pack = Data.Semigroup.First-  unpack (Data.Semigroup.First a) = a---- | @since 0.5.1-instance Newtype (Data.Semigroup.Last a) where-  type O (Data.Semigroup.Last a) = a-  pack = Data.Semigroup.Last-  unpack (Data.Semigroup.Last a) = a---- | @since 0.5.1-instance Newtype (WrappedMonoid m) where-  type O (WrappedMonoid m) = m-  pack = WrapMonoid-  unpack (WrapMonoid m) = m---- | @since 0.5.1-instance Newtype (Option a) where-  type O (Option a) = Maybe a-  pack = Option-  unpack (Option x) = x-#endif+import Control.Newtype.Generics
+ Control/Newtype/Generics.hs view
@@ -0,0 +1,374 @@+{-# LANGUAGE CPP                        #-}+{-# LANGUAGE DeriveGeneric              #-}+{-# LANGUAGE DefaultSignatures          #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# LANGUAGE TypeFamilies               #-}+{-# LANGUAGE UndecidableInstances       #-}+{- |+The 'Newtype' typeclass and related functions.+Primarily pulled from Conor McBride's Epigram work. Some examples:++>>> ala Sum foldMap [1,2,3,4]+10++>>> ala Endo foldMap [(+1), (+2), (subtract 1), (*2)] 3+8++>>> under2 Min (<>) 2 1+1++>>> over All not (All False)+All {getAll = True)++This package includes 'Newtype' instances for all the (non-GHC\/foreign)+newtypes in base (as seen in the examples).+However, there are neat things you can do with this with+/any/ newtype and you should definitely define your own 'Newtype'+instances for the power of this library.+For example, see @ala Cont traverse@, with the proper 'Newtype' instance for Cont.+You can easily define new instances for your newtypes with the help of GHC.Generics++ > {-# LANGUAGE DeriveGeneric #-}+ > import GHC.Generics+ >+ > (...)+ > newtype Example = Example Int+ >   deriving (Generic)+ >+ > instance Newtype Example+ >++This avoids the use of Template Haskell (TH) to get new instances.+-}+module Control.Newtype.Generics+  ( Newtype(..)+  , op+  , ala+  , ala'+  , under+  , over+  , under2+  , over2+  , underF+  , overF+  ) where++import Control.Applicative+import Control.Arrow+import Data.Functor.Compose+import Data.Functor.Identity+#if MIN_VERSION_base(4,7,0)+import Data.Fixed+#endif+import Data.Monoid+import Data.Ord+#if MIN_VERSION_base(4,9,0)+import qualified Data.Semigroup+import Data.Semigroup (Min(..), Max(..), WrappedMonoid(..), Option(..))+#endif+import GHC.Generics+{-import Generics.Deriving-}++-- | Given a newtype @n@, we will always have the same unwrapped type @o@,+-- meaning we can represent this with a fundep @n -> o@.+--+-- Any instance of this class just needs to let @pack@ equal to the newtype's+-- constructor, and let @unpack@ destruct the newtype with pattern matching.+{-class Newtype n o | n -> o where-}+  {-pack :: o -> n-}+  {-unpack :: n -> o-}+++-- Generic Newtype+class GNewtype n where+  type GO n :: *+  gpack   :: GO n -> n p+  gunpack :: n p  -> GO n++-- We only need one instance, if these generic functions are only to work for+-- newtypes, as these have a fixed form. For example, for a newtype X = Y,+-- Rep X = D1 ... (C1 ... (S1 ... (K1 ... Y)))+instance GNewtype (D1 d (C1 c (S1 s (K1 i a)))) where+  type GO (D1 d (C1 c (S1 s (K1 i a)))) = a+  gpack   x                     = M1 (M1 (M1 (K1 x)))+  gunpack (M1 (M1 (M1 (K1 x)))) = x++-- Original Newtype class, extended with generic defaults (trivial) and deprived+-- of the second type argument (less trivial, as it involves a type family with+-- a default, plus an equality constraint for the related type family in+-- GNewtype). We do get rid of MultiParamTypeClasses and FunctionalDependencies,+-- though.++-- | As long as the type @n@ is an instance of Generic, you can create an instance+-- with just @instance Newtype n@+class Newtype n where+  type O n :: *+  type O n = GO (Rep n)++  pack   :: O n -> n+  default pack :: (Generic n, GNewtype (Rep n), O n ~ GO (Rep n)) => O n -> n+  pack = to . gpack++  unpack :: n -> O n+  default unpack :: (Generic n, GNewtype (Rep n), O n ~ GO (Rep n)) => n -> O n+  unpack = gunpack . from++-- |+-- This function serves two purposes:+--+-- 1. Giving you the unpack of a newtype without you needing to remember the name.+--+-- 2. Showing that the first parameter is /completely ignored/ on the value level,+--    meaning the only reason you pass in the constructor is to provide type+--    information.  Typeclasses sure are neat.+--+-- >>> op Identity (Identity 3)+-- 3+op :: (Newtype n,o ~ O n ) => (o -> n) -> n -> o+op _ = unpack++-- | The workhorse of the package. Given a "packer" and a \"higher order function\" (/hof/),+-- it handles the packing and unpacking, and just sends you back a regular old+-- function, with the type varying based on the /hof/ you passed.+--+-- The reason for the signature of the /hof/ is due to 'ala' not caring about structure.+-- To illustrate why this is important, consider this alternative implementation of 'under2':+--+-- > under2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)+-- >        => (o -> n) -> (n -> n -> n') -> (o -> o -> o')+-- > under2' pa f o0 o1 = ala pa (\p -> uncurry f . bimap p p) (o0, o1)+--+-- Being handed the "packer", the /hof/ may apply it in any structure of its choosing –+-- in this case a tuple.+--+-- >>> ala Sum foldMap [1,2,3,4]+-- 10+ala :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)+    => (o -> n) -> ((o -> n) -> b -> n') -> (b -> o')+ala pa hof = ala' pa hof id++-- | This is the original function seen in Conor McBride's work.+-- The way it differs from the 'ala' function in this package,+-- is that it provides an extra hook into the \"packer\" passed to the hof.+-- However, this normally ends up being @id@, so 'ala' wraps this function and+-- passes @id@ as the final parameter by default.+-- If you want the convenience of being able to hook right into the hof,+-- you may use this function.+--+-- >>> ala' Sum foldMap length ["hello", "world"]+-- 10+--+-- >>> ala' First foldMap (readMaybe @Int) ["x", "42", "1"]+-- Just 42+ala' :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)+     => (o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> (b -> o')+ala' _ hof f = unpack . hof (pack . f)++-- | A very simple operation involving running the function \'under\' the newtype.+--+-- >>> under Product (stimes 3) 3+-- 27+under :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)+      => (o -> n) -> (n -> n') -> (o -> o')+under _ f = unpack . f . pack++-- | The opposite of 'under'. I.e., take a function which works on the+-- underlying types, and switch it to a function that works on the newtypes.+--+-- >>> over All not (All False)+-- All {getAll = True}+over :: (Newtype n,  Newtype n', o' ~ O n', o ~ O n)+     => (o -> n) -> (o -> o') -> (n -> n')+over _ f = pack . f . unpack++-- | Lower a binary function to operate on the underlying values.+--+-- >>> under2 Any (<>) True False+-- True+--+-- @since 0.5.2+under2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)+       => (o -> n) -> (n -> n -> n') -> (o -> o -> o')+under2 _ f o0 o1 = unpack $ f (pack o0) (pack o1)++-- | The opposite of 'under2'.+--+-- @since 0.5.2+over2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n)+       => (o -> n) -> (o -> o -> o') -> (n -> n -> n')+over2 _ f n0 n1 = pack $ f (unpack n0) (unpack n1)++-- | 'under' lifted into a Functor.+underF :: (Newtype n, Newtype n', o' ~ O n', o ~ O n, Functor f, Functor g)+       => (o -> n) -> (f n -> g n') -> (f o -> g o')+underF _ f = fmap unpack . f . fmap pack++-- | 'over' lifted into a Functor.+overF :: (Newtype n, Newtype n', o' ~ O n', o ~ O n, Functor f, Functor g)+      => (o -> n) -> (f o -> g o') -> (f n -> g n')+overF _ f = fmap pack . f . fmap unpack++-- Instances from Control.Applicative++instance Newtype (WrappedMonad m a) where+  type O (WrappedMonad m a) = m a+  pack = WrapMonad+  unpack (WrapMonad a) = a++instance Newtype (WrappedArrow a b c) where+  type O (WrappedArrow a b c) = a b c+  pack = WrapArrow+  unpack (WrapArrow a) = a++instance Newtype (ZipList a) where+  type O (ZipList a) = [a]+  pack = ZipList+  unpack (ZipList a) = a++-- Instances from Control.Arrow++instance Newtype (Kleisli m a b) where+  type O (Kleisli m a b) = a -> m b+  pack = Kleisli+  unpack (Kleisli a) = a++instance Newtype (ArrowMonad a b) where+  type O (ArrowMonad a b) = a () b+  pack = ArrowMonad+  unpack (ArrowMonad a) = a++#if MIN_VERSION_base(4,7,0)+-- Instances from Data.Fixed++-- | @since 0.5.1+instance Newtype (Fixed a) where+  type O (Fixed a) = Integer+  pack = MkFixed+  unpack (MkFixed x) = x+#endif++-- Instances from Data.Functor.Compose++-- | @since 0.5.1+instance Newtype (Compose f g a) where+  type O (Compose f g a) = f (g a)+  pack = Compose+  unpack (Compose x) = x++-- Instances from Data.Functor.Const++instance Newtype (Const a x) where+  type O (Const a x) = a+  pack = Const+  unpack (Const a) = a++-- Instances from Data.Functor.Identity++-- | @since 0.5.1+instance Newtype (Identity a) where+  type O (Identity a) = a+  pack = Identity+  unpack (Identity a) = a++-- Instances from Data.Monoid++-- | @since 0.5.1+instance Newtype (Dual a) where+  type O (Dual a) = a+  pack = Dual+  unpack (Dual a) = a++instance Newtype (Endo a) where+  type O (Endo a) = (a -> a)+  pack = Endo+  unpack (Endo a) = a++instance Newtype All where+  type O All = Bool+  pack = All+  unpack (All x) = x++instance Newtype Any where+  type O Any = Bool+  pack = Any+  unpack (Any x) = x++instance Newtype (Sum a) where+  type O (Sum a) = a+  pack = Sum+  unpack (Sum a) = a++instance Newtype (Product a) where+  type O (Product a) = a+  pack = Product+  unpack (Product a) = a++instance Newtype (First a) where+  type O (First a) = Maybe a+  pack = First+  unpack (First a) = a++instance Newtype (Last a) where+  type O (Last a) = Maybe a+  pack = Last+  unpack (Last a) = a++#if MIN_VERSION_base(4,8,0)+-- | @since 0.5.1+instance Newtype (Alt f a) where+  type O (Alt f a) = f a+  pack = Alt+  unpack (Alt x) = x+#endif++-- Instances from Data.Ord++-- | @since 0.5.1+instance Newtype (Down a) where+  type O (Down a) = a+  pack = Down+  unpack (Down a) = a+++#if MIN_VERSION_base(4,9,0)+-- Instances from Data.Semigroup++-- | @since 0.5.1+instance Newtype (Min a) where+  type O (Min a) = a+  pack = Min+  unpack (Min a) = a++-- | @since 0.5.1+instance Newtype (Max a) where+  type O (Max a) = a+  pack = Max+  unpack (Max a) = a++-- | @since 0.5.1+instance Newtype (Data.Semigroup.First a) where+  type O (Data.Semigroup.First a) = a+  pack = Data.Semigroup.First+  unpack (Data.Semigroup.First a) = a++-- | @since 0.5.1+instance Newtype (Data.Semigroup.Last a) where+  type O (Data.Semigroup.Last a) = a+  pack = Data.Semigroup.Last+  unpack (Data.Semigroup.Last a) = a++-- | @since 0.5.1+instance Newtype (WrappedMonoid m) where+  type O (WrappedMonoid m) = m+  pack = WrapMonoid+  unpack (WrapMonoid m) = m++-- | @since 0.5.1+instance Newtype (Option a) where+  type O (Option a) = Maybe a+  pack = Option+  unpack (Option x) = x+#endif
README.md view
@@ -1,38 +1,7 @@ newtype-generics ================ -A typeclass and set of functions for working with newtypes.-Fork of the code published by Darius Jahandarie [here](http://hackage.haskell.org/package/newtype-0.2),-with the addition of generics.--The 'Newtype' typeclass and related functions: `op`, `ala`, `ala'`, `under`. -Primarly pulled from Conor McBride's Epigram work. Some examples:--```--- foldMaps the list ala the Sum newtype. This results in 10.-ala Sum foldMap [1,2,3,4] ---- foldMaps the list ala the Product newtype. This results in 24.-ala Product foldMap [1,2,3,4] ---- foldMaps the list ala the Endo newtype. This results in 8.-ala Endo foldMap [(+1), (+2), (subtract 1), (*2)] 3 -```--_NB:_ `Data.Foldable.foldMap` is a generalized `mconcatMap` which is a generalized `concatMap`.--This package includes `Newtype` instances for all the (non-GHC/foreign) newtypes in base (as seen in the examples).-However, there are neat things you can do with this with /any/ newtype and you should definitely define your own 'Newtype' instances for the power of this library.-For example, see `ala Cont traverse`, with the proper `Newtype` instance for Cont.--This could of course be eased with the addition of generics for version 0.3:--```-{-# LANGUAGE DeriveGeneric              #-}--import GHC.Generics-(...)-newtype Example = Example Int (deriving Generic)-instance Newtype Example-```+# bsb-http-chunked +[![Build Status](https://travis-ci.org/sjakobi/newtype-generics.svg?branch=master)](https://travis-ci.org/sjakobi/newtype-generics)+[![Hackage](https://img.shields.io/hackage/v/newtype-generics.svg)](http://hackage.haskell.org/package/newtype-generics)
bench/main.hs view
@@ -4,8 +4,9 @@  import Criterion import Criterion.Main-import Control.Newtype+import Control.Newtype.Generics import Data.Coerce+import Data.Foldable (foldMap) import Data.Semigroup import GHC.Generics 
newtype-generics.cabal view
@@ -1,6 +1,6 @@ Name:                newtype-generics-Version:             0.5.2.2-Synopsis:            A typeclass and set of functions for working with newtypes, with generics support.+Version:             0.5.3+Synopsis:            A typeclass and set of functions for working with newtypes Description:         Per Conor McBride, the Newtype typeclass represents the packing and unpacking of a newtype,                      and allows you to operate under that newtype with functions such as ala.                      Generics support was added in version 0.4, making this package a full replacement@@ -9,11 +9,13 @@ License-file:        LICENSE Author:              Darius Jahandarie, Conor McBride, João Cristóvão, Simon Jakobi Maintainer:          Simon Jakobi <simon.jakobi@gmail.com>+Homepage:            http://github.com/sjakobi/bsb-http-chunked Category:            Control Build-type:          Simple Extra-source-files:  CHANGELOG.md, README.md Cabal-version:       >=1.10 Tested-with:+  GHC==8.4.1,   GHC==8.2.1,   GHC==8.0.2,   GHC==7.10.3,@@ -22,6 +24,7 @@  Library   Exposed-modules:     Control.Newtype+                     , Control.Newtype.Generics   Build-depends:       base >= 4.6 && < 4.13                      , transformers < 0.6   Ghc-options: -Wall@@ -29,7 +32,7 @@  source-repository head   type: git-  location: https://github.com/jcristovao/newtype-generics+  location: https://github.com/sjakobi/newtype-generics  test-suite test   type:               exitcode-stdio-1.0@@ -39,7 +42,6 @@   build-depends:      base                     , newtype-generics                     , hspec             >= 2.1-                    , HUnit             >= 1.2.5.2   default-language:   Haskell2010   build-tool-depends: hspec-discover:hspec-discover >= 2.1 @@ -47,7 +49,7 @@   type:               exitcode-stdio-1.0   main-is:            main.hs   hs-source-dirs:     bench-  build-depends:      base+  build-depends:      base >= 4.7                     , criterion                     , newtype-generics                     , semigroups
test/Control/NewtypeSpec.hs view
@@ -9,7 +9,7 @@ import Prelude  import Data.Monoid-import Control.Newtype+import Control.Newtype.Generics import GHC.Generics  import Test.Hspec