License | BSD-3-Clause |
---|---|
Safe Haskell | Trustworthy |
Language | Haskell2010 |
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 "
", with the proper
ala
Cont
traverse
Newtype
instance for
Cont
.
Synopsis
- class Newtype n o | n -> o where
- op :: Newtype n o => (o -> n) -> n -> o
- ala :: ( Newtype n o, Newtype n' o') => (o -> n) -> ((o -> n) -> b -> n') -> b -> o'
- ala' :: ( Newtype n o, Newtype n' o') => (o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> b -> o'
- under :: ( Newtype n o, Newtype n' o') => (o -> n) -> (n -> n') -> o -> o'
- over :: ( Newtype n o, Newtype n' o') => (o -> n) -> (o -> o') -> n -> n'
- underF :: ( Newtype n o, Newtype n' o', Functor f) => (o -> n) -> (f n -> f n') -> f o -> f o'
- overF :: ( Newtype n o, Newtype n' o', Functor f) => (o -> n) -> (f o -> f o') -> f n -> f n'
Documentation
class Newtype n o | n -> o where Source #
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.
Nothing
Instances
Newtype All Bool Source # | |
Newtype Any Bool Source # | |
Newtype ( Identity a) a Source # |
Since: 0.2.1.0 |
Newtype ( Dual a) a Source # |
Since: 0.2.1.0 |
Newtype ( Sum a) a Source # | |
Newtype ( Product a) a Source # | |
Newtype ( Down a) a Source # |
NOTE
: Type & instance only available with
Since: 0.2.1.0 |
Newtype ( ZipList a) [a] Source # | |
Newtype ( First a) ( Maybe a) Source # | |
Newtype ( Last a) ( Maybe a) Source # | |
Newtype ( Endo a) (a -> a) Source # | |
Newtype ( Fixed a) Integer Source # |
Since: 0.2.1.0 |
Newtype ( WrappedMonad m a) (m a) Source # | |
Defined in Control.Newtype pack :: m a -> WrappedMonad m a Source # unpack :: WrappedMonad m a -> m a Source # |
|
ArrowApply a => Newtype ( ArrowMonad a b) (a () b) Source # | |
Defined in Control.Newtype pack :: a () b -> ArrowMonad a b Source # unpack :: ArrowMonad a b -> a () b Source # |
|
Newtype ( Const a x) a Source # | |
Newtype ( Ap f a) (f a) Source # |
NOTE
: Type & instance only available with
Since: 0.2.1.0 |
Newtype ( Alt f a) (f a) Source # |
NOTE
: Type & instance only available with
Since: 0.2.1.0 |
Newtype ( WrappedArrow a b c) (a b c) Source # | |
Defined in Control.Newtype pack :: a b c -> WrappedArrow a b c Source # unpack :: WrappedArrow a b c -> a b c Source # |
|
Newtype ( Kleisli m a b) (a -> m b) Source # |
Since: 0.2 |
Newtype ( Compose f g a) (f (g a)) Source # |
Since: 0.2.1.0 |
op :: Newtype n o => (o -> n) -> n -> o Source #
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.
ala :: ( Newtype n o, Newtype n' o') => (o -> n) -> ((o -> n) -> b -> n') -> b -> o' Source #
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) -> ((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.
under :: ( Newtype n o, Newtype n' o') => (o -> n) -> (n -> n') -> o -> o' Source #
A very simple operation involving running the function "under" the newtype. Suffers from the problems mentioned in the
ala
function's documentation.
over :: ( Newtype n o, Newtype n' o') => (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.
Since: 0.2