-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | A typeclass and set of functions for working with newtypes.
--   
--   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. See
--   Control.Newtype for documentation and examples.
@package newtype
@version 0.2.2.0

-- | The Newtype typeclass and related functions: op,
--   ala, ala', under. Primarly pulled from Conor
--   McBride's Epigram work. Some examples:
--   
--   
--   >>> ala Sum foldMap [1,2,3,4] -- foldMaps the list ala the Sum newtype
--   10
--   
--   
--   
--   >>> ala Product foldMap [1,2,3,4] -- foldMaps the list ala the Product newtype
--   24
--   
--   
--   
--   >>> ala Endo foldMap [(+1), (+2), (subtract 1), (*2)] 3 -- foldMaps the list ala the Endo newtype
--   8
--   
--   
--   NB: 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.
module Control.Newtype

-- | 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.
--   
--   Starting with newtype-0.2.2.0, default method implementations
--   are provided using Data.Coerce for GHC 7.8 (i.e.
--   base-4.7.0.0) and later, i.e.:
--   
--   
--   pack   = coerce
--   unpack = coerce
--   
--   
--   When omitting the method definitions with GHC 7.4 and 7.6 a compile
--   error will be triggered.
--   
--   Consequently, if your code relies on these default methods make sure
--   to state
--   
--   
--   build-depends: newtype ^>= 0.2.2.0
--   
--   
--   In your .cabal package description.
class Newtype n o | n -> o
pack :: Newtype n o => o -> n
unpack :: Newtype n o => n -> o
pack :: (Newtype n o, Coercible o n) => o -> n
unpack :: (Newtype n o, Coercible n o) => n -> o

-- | This function serves two purposes:
--   
--   
--   
- Giving you the unpack of a newtype without you needing to
--   remember the name.
--   
- 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 :: Newtype n o => (o -> n) -> n -> o

-- | The workhorse of the package. Given a pack and a "higher order
--   function", it handles the packing and unpacking, and just sends you
--   back a regular old function, with the type varying based on the
--   hof (higher-order function) you passed.
--   
--   The reason for the signature of the hof is due to ala not
--   caring about structure. To illustrate why this is important, another
--   function in this package is under. It is not extremely useful;
--   under2 might be more useful (with e.g., mappend), but
--   then we already digging the trench of "What about under3?
--   under4?". The solution utilized here is to just hand off the
--   "packer" to the hof. That way your structure can be imposed in the
--   hof, whatever you may want it to be (e.g., List, Traversable).
ala :: (Newtype n o, Newtype n' o') => (o -> n) -> ((o -> n) -> b -> n') -> b -> o'

-- | 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' :: (Newtype n o, Newtype n' o') => (o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> b -> o'

-- | A very simple operation involving running the function "under" the
--   newtype. Suffers from the problems mentioned in the ala
--   function's documentation.
under :: (Newtype n o, Newtype n' o') => (o -> n) -> (n -> n') -> o -> o'

-- | 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 :: (Newtype n o, Newtype n' o') => (o -> n) -> (o -> o') -> n -> n'

-- | under lifted into a Functor.
underF :: (Newtype n o, Newtype n' o', Functor f) => (o -> n) -> (f n -> f n') -> f o -> f o'

-- | over lifted into a Functor.
overF :: (Newtype n o, Newtype n' o', Functor f) => (o -> n) -> (f o -> f o') -> f n -> f n'
instance Control.Newtype.Newtype Data.Semigroup.Internal.All GHC.Types.Bool
instance Control.Newtype.Newtype Data.Semigroup.Internal.Any GHC.Types.Bool
instance Control.Newtype.Newtype (Data.Semigroup.Internal.Sum a) a
instance Control.Newtype.Newtype (Data.Semigroup.Internal.Product a) a
instance Control.Newtype.Newtype (Control.Arrow.Kleisli m a b) (a -> m b)
instance Control.Newtype.Newtype (Control.Applicative.WrappedMonad m a) (m a)
instance Control.Newtype.Newtype (Control.Applicative.WrappedArrow a b c) (a b c)
instance Control.Newtype.Newtype (Control.Applicative.ZipList a) [a]
instance Control.Newtype.Newtype (Data.Functor.Const.Const a x) a
instance Control.Newtype.Newtype (Data.Semigroup.Internal.Endo a) (a -> a)
instance Control.Newtype.Newtype (Data.Monoid.First a) (GHC.Maybe.Maybe a)
instance Control.Newtype.Newtype (Data.Monoid.Last a) (GHC.Maybe.Maybe a)
instance Control.Arrow.ArrowApply a => Control.Newtype.Newtype (Control.Arrow.ArrowMonad a b) (a () b)
instance Control.Newtype.Newtype (Data.Fixed.Fixed a) GHC.Integer.Type.Integer
instance Control.Newtype.Newtype (Data.Semigroup.Internal.Dual a) a
instance Control.Newtype.Newtype (Data.Semigroup.Internal.Alt f a) (f a)
instance Control.Newtype.Newtype (Data.Ord.Down a) a
instance Control.Newtype.Newtype (Data.Functor.Identity.Identity a) a
instance Control.Newtype.Newtype (Data.Functor.Compose.Compose f g a) (f (g a))
instance Control.Newtype.Newtype (Data.Monoid.Ap f a) (f a)
