newtype-generics-0.6.2: A typeclass and set of functions for working with newtypes

Safe Haskell | Safe-Inferred
Language | Haskell2010

Control.Newtype.Generics

Description

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.

Synopsis

- class Newtype n where
  - type O n
  - pack :: O n -> n
  - unpack :: n -> O n
- op :: (Newtype n, o ~ O n) => (o -> n) -> n -> o
- ala :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> ((o -> n) -> b -> n') -> b -> o'
- ala' :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> b -> o'
- under :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (n -> n') -> o -> o'
- over :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (o -> o') -> n -> n'
- under2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (n -> n -> n') -> o -> o -> o'
- over2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (o -> o -> o') -> n -> n -> n'
- 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'
- 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'

# Documentation

class Newtype n where Source #

As long as the type `n` is an instance of Generic, you can create an instance with just `instance Newtype n`

Minimal complete definition

Nothing

Associated Types

type O n Source #

type O n = GO (Rep n)

Methods

pack :: O n -> n Source #

default pack :: (Generic n, GNewtype (Rep n), O n ~ GO (Rep n)) => O n -> n Source #

unpack :: n -> O n Source #

default unpack :: (Generic n, GNewtype (Rep n), O n ~ GO (Rep n)) => n -> O n Source #

#### Instances

Instances details

Newtype All Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O All |
Instance details Defined in Control.Newtype.Generics type O All = Bool

Methods

pack :: O All -> All Source #

unpack :: All -> O All Source #

Newtype Any Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O Any |
Instance details Defined in Control.Newtype.Generics type O Any = Bool

Methods

pack :: O Any -> Any Source #

unpack :: Any -> O Any Source #

Newtype (First a) Source # | Since: 0.5.1

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (First a) |
Instance details Defined in Control.Newtype.Generics type O (First a) = a

Methods

pack :: O (First a) -> First a Source #

unpack :: First a -> O (First a) Source #

Newtype (Last a) Source # | Since: 0.5.1

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Last a) |
Instance details Defined in Control.Newtype.Generics type O (Last a) = a

Methods

pack :: O (Last a) -> Last a Source #

unpack :: Last a -> O (Last a) Source #

Newtype (Max a) Source # | Since: 0.5.1

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Max a) |
Instance details Defined in Control.Newtype.Generics type O (Max a) = a

Methods

pack :: O (Max a) -> Max a Source #

unpack :: Max a -> O (Max a) Source #

Newtype (Min a) Source # | Since: 0.5.1

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Min a) |
Instance details Defined in Control.Newtype.Generics type O (Min a) = a

Methods

pack :: O (Min a) -> Min a Source #

unpack :: Min a -> O (Min a) Source #

Newtype (WrappedMonoid m) Source # | Since: 0.5.1

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (WrappedMonoid m) |
Instance details Defined in Control.Newtype.Generics type O (WrappedMonoid m) = m

Methods

pack :: O (WrappedMonoid m) -> WrappedMonoid m Source #

unpack :: WrappedMonoid m -> O (WrappedMonoid m) Source #

Newtype (Identity a) Source # | Since: 0.5.1

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Identity a) |
Instance details Defined in Control.Newtype.Generics type O (Identity a) = a

Methods

pack :: O (Identity a) -> Identity a Source #

unpack :: Identity a -> O (Identity a) Source #

Newtype (First a) Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (First a) |
Instance details Defined in Control.Newtype.Generics type O (First a) = Maybe a

Methods

pack :: O (First a) -> First a Source #

unpack :: First a -> O (First a) Source #

Newtype (Last a) Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Last a) |
Instance details Defined in Control.Newtype.Generics type O (Last a) = Maybe a

Methods

pack :: O (Last a) -> Last a Source #

unpack :: Last a -> O (Last a) Source #

Newtype (Down a) Source # | Since: 0.5.1

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Down a) |
Instance details Defined in Control.Newtype.Generics type O (Down a) = a

Methods

pack :: O (Down a) -> Down a Source #

unpack :: Down a -> O (Down a) Source #

Newtype (Dual a) Source # | Since: 0.5.1

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Dual a) |
Instance details Defined in Control.Newtype.Generics type O (Dual a) = a

Methods

pack :: O (Dual a) -> Dual a Source #

unpack :: Dual a -> O (Dual a) Source #

Newtype (Endo a) Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Endo a) |
Instance details Defined in Control.Newtype.Generics type O (Endo a) = a -> a

Methods

pack :: O (Endo a) -> Endo a Source #

unpack :: Endo a -> O (Endo a) Source #

Newtype (Product a) Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Product a) |
Instance details Defined in Control.Newtype.Generics type O (Product a) = a

Methods

pack :: O (Product a) -> Product a Source #

unpack :: Product a -> O (Product a) Source #

Newtype (Sum a) Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Sum a) |
Instance details Defined in Control.Newtype.Generics type O (Sum a) = a

Methods

pack :: O (Sum a) -> Sum a Source #

unpack :: Sum a -> O (Sum a) Source #

Newtype (ZipList a) Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (ZipList a) |
Instance details Defined in Control.Newtype.Generics type O (ZipList a) = [a]

Methods

pack :: O (ZipList a) -> ZipList a Source #

unpack :: ZipList a -> O (ZipList a) Source #

Newtype (WrappedMonad m a) Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (WrappedMonad m a) |
Instance details Defined in Control.Newtype.Generics type O (WrappedMonad m a) = m a

Methods

pack :: O (WrappedMonad m a) -> WrappedMonad m a Source #

unpack :: WrappedMonad m a -> O (WrappedMonad m a) Source #

Newtype (Fixed a) Source # | Since: 0.5.1

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Fixed a) |
Instance details Defined in Control.Newtype.Generics type O (Fixed a) = Integer

Methods

pack :: O (Fixed a) -> Fixed a Source #

unpack :: Fixed a -> O (Fixed a) Source #

Newtype (ArrowMonad a b) Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (ArrowMonad a b) |
Instance details Defined in Control.Newtype.Generics type O (ArrowMonad a b) = a () b

Methods

pack :: O (ArrowMonad a b) -> ArrowMonad a b Source #

unpack :: ArrowMonad a b -> O (ArrowMonad a b) Source #

Newtype (WrappedArrow a b c) Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (WrappedArrow a b c) |
Instance details Defined in Control.Newtype.Generics type O (WrappedArrow a b c) = a b c

Methods

pack :: O (WrappedArrow a b c) -> WrappedArrow a b c Source #

unpack :: WrappedArrow a b c -> O (WrappedArrow a b c) Source #

Newtype (Kleisli m a b) Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Kleisli m a b) |
Instance details Defined in Control.Newtype.Generics type O (Kleisli m a b) = a -> m b

Methods

pack :: O (Kleisli m a b) -> Kleisli m a b Source #

unpack :: Kleisli m a b -> O (Kleisli m a b) Source #

Newtype (Const a x) Source # |

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Const a x) |
Instance details Defined in Control.Newtype.Generics type O (Const a x) = a

Methods

pack :: O (Const a x) -> Const a x Source #

unpack :: Const a x -> O (Const a x) Source #

Newtype (Ap f a) Source # | Since: 0.5.4

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Ap f a) |
Instance details Defined in Control.Newtype.Generics type O (Ap f a) = f a

Methods

pack :: O (Ap f a) -> Ap f a Source #

unpack :: Ap f a -> O (Ap f a) Source #

Newtype (Alt f a) Source # | Since: 0.5.1

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Alt f a) |
Instance details Defined in Control.Newtype.Generics type O (Alt f a) = f a

Methods

pack :: O (Alt f a) -> Alt f a Source #

unpack :: Alt f a -> O (Alt f a) Source #

Newtype (Compose f g a) Source # | Since: 0.5.1

Instance details

Defined in Control.Newtype.Generics

Associated Types

type O (Compose f g a) |
Instance details Defined in Control.Newtype.Generics type O (Compose f g a) = f (g a)

Methods

pack :: O (Compose f g a) -> Compose f g a Source #

unpack :: Compose f g a -> O (Compose f g a) Source #

op :: (Newtype n, o ~ O n) => (o -> n) -> n -> o Source #

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

ala :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> ((o -> n) -> b -> n') -> b -> o' Source #

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) -> ((a -> n) -> b -> n') -> (a -> o) -> b -> o' Source #

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

under :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (n -> n') -> o -> o' Source #

A very simple operation involving running the function 'under' the newtype.

    >>> under Product (stimes 3) 3
    27

over :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (o -> o') -> n -> n' Source #

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}

under2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (n -> n -> n') -> o -> o -> o' Source #

Lower a binary function to operate on the underlying values.

    >>> under2 Any (<>) True False
    True

Since: 0.5.2

over2 :: (Newtype n, Newtype n', o' ~ O n', o ~ O n) => (o -> n) -> (o -> o -> o') -> n -> n -> n' Source #

The opposite of `under2`.

Since: 0.5.2

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' Source #

`under` 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' Source #

`over` lifted into a Functor.