-- 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 operatate under that newtype
-- with functions such as ala.
@package newtype
@version 0.2
-- | 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. This results in 10.
--
--
--
-- ala Product foldMap [1,2,3,4] -- foldMaps the list ala the Product newtype. This results in 24.
--
--
--
-- ala Endo foldMap [(+1), (+2), (subtract 1), (*2)] 3 -- foldMaps the list ala the Endo newtype. This results in 8.
--
--
-- 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.
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.
class Newtype n o | n -> o
pack :: Newtype n o => o -> n
unpack :: Newtype 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
-- 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 ArrowApply a => Newtype (ArrowMonad a b) (a () b)
instance Newtype (Last a) (Maybe a)
instance Newtype (First a) (Maybe a)
instance Newtype (Endo a) (a -> a)
instance Newtype (Const a x) a
instance Newtype (ZipList a) [a]
instance Newtype (WrappedArrow a b c) (a b c)
instance Newtype (WrappedMonad m a) (m a)
instance Newtype (Kleisli m a b) (a -> m b)
instance Newtype (Product a) a
instance Newtype (Sum a) a
instance Newtype Any Bool
instance Newtype All Bool