Data.Newtype
#Newtype
class (Coercible t a) <= Newtype t a | t -> a
A type class for newtype
s to enable convenient wrapping and unwrapping,
and the use of the other functions in this module.
The compiler can derive instances of Newtype
automatically:
newtype EmailAddress = EmailAddress String
derive instance newtypeEmailAddress :: Newtype EmailAddress _
Note that deriving for Newtype
instances requires that the type be
defined as newtype
rather than data
declaration (even if the data
structurally fits the rules of a newtype
), and the use of a wildcard for
the wrapped type.
Instances
#un
#ala
ala :: forall f t a s b. Coercible (f t) (f a) => Newtype t a => Newtype s b => (a -> t) -> ((b -> s) -> f t) -> f a
This combinator is for when you have a higher order function that you want
to use in the context of some newtype - foldMap
being a common example:
ala Additive foldMap [1,2,3,4] -- 10
ala Multiplicative foldMap [1,2,3,4] -- 24
ala Conj foldMap [true, false] -- false
ala Disj foldMap [true, false] -- true
#alaF
alaF :: forall f g t a s b. Coercible (f t) (f a) => Coercible (g s) (g b) => Newtype t a => Newtype s b => (a -> t) -> (f t -> g s) -> f a -> g b
Similar to ala
but useful for cases where you want to use an additional
projection with the higher order function:
alaF Additive foldMap String.length ["hello", "world"] -- 10
alaF Multiplicative foldMap Math.abs [1.0, -2.0, 3.0, -4.0] -- 24.0
The type admits other possibilities due to the polymorphic Functor
constraints, but the case described above works because ((->) a) is a
Functor
.
#over
over :: forall t a s b. Newtype t a => Newtype s b => (a -> t) -> (a -> b) -> t -> s
Lifts a function operate over newtypes. This can be used to lift a
function to manipulate the contents of a single newtype, somewhat like
map
does for a Functor
:
newtype Label = Label String
derive instance newtypeLabel :: Newtype Label _
toUpperLabel :: Label -> Label
toUpperLabel = over Label String.toUpper
But the result newtype is polymorphic, meaning the result can be returned as an alternative newtype:
newtype UppercaseLabel = UppercaseLabel String
derive instance newtypeUppercaseLabel :: Newtype UppercaseLabel _
toUpperLabel' :: Label -> UppercaseLabel
toUpperLabel' = over Label String.toUpper
#overF
overF :: forall f g t a s b. Coercible (f a) (f t) => Coercible (g b) (g s) => Newtype t a => Newtype s b => (a -> t) -> (f a -> g b) -> f t -> g s
Much like over
, but where the lifted function operates on values in a
Functor
:
findLabel :: String -> Array Label -> Maybe Label
findLabel s = overF Label (Foldable.find (_ == s))
The above example also demonstrates that the functor type is polymorphic
here too, the input is an Array
but the result is a Maybe
.
#under
under :: forall t a s b. Newtype t a => Newtype s b => (a -> t) -> (t -> s) -> a -> b
The opposite of over
: lowers a function that operates on Newtype
d
values to operate on the wrapped value instead.
newtype Degrees = Degrees Number
derive instance newtypeDegrees :: Newtype Degrees _
newtype NormalDegrees = NormalDegrees Number
derive instance newtypeNormalDegrees :: Newtype NormalDegrees _
normaliseDegrees :: Degrees -> NormalDegrees
normaliseDegrees (Degrees deg) = NormalDegrees (deg % 360.0)
asNormalDegrees :: Number -> Number
asNormalDegrees = under Degrees normaliseDegrees
As with over
the Newtype
is polymorphic, as illustrated in the example
above - both Degrees
and NormalDegrees
are instances of Newtype
,
so even though normaliseDegrees
changes the result type we can still put
a Number
in and get a Number
out via under
.
#underF
underF :: forall f g t a s b. Coercible (f t) (f a) => Coercible (g s) (g b) => Newtype t a => Newtype s b => (a -> t) -> (f t -> g s) -> f a -> g b
Much like under
, but where the lifted function operates on values in a
Functor
:
newtype EmailAddress = EmailAddress String
derive instance newtypeEmailAddress :: Newtype EmailAddress _
isValid :: EmailAddress -> Boolean
isValid x = false -- imagine a slightly less strict predicate here
findValidEmailString :: Array String -> Maybe String
findValidEmailString = underF EmailAddress (Foldable.find isValid)
The above example also demonstrates that the functor type is polymorphic
here too, the input is an Array
but the result is a Maybe
.
#over2
over2 :: forall t a s b. Newtype t a => Newtype s b => (a -> t) -> (a -> a -> b) -> t -> t -> s
Lifts a binary function to operate over newtypes.
newtype Meter = Meter Int
derive newtype instance newtypeMeter :: Newtype Meter _
newtype SquareMeter = SquareMeter Int
derive newtype instance newtypeSquareMeter :: Newtype SquareMeter _
area :: Meter -> Meter -> SquareMeter
area = over2 Meter (*)
The above example also demonstrates that the return type is polymorphic here too.
#overF2
#under2
#underF2
#traverse
Modules
- Control.Applicative
- Control.Apply
- Control.Bind
- Control.Category
- Control.Monad
- Control.Semigroupoid
- Data.Boolean
- Data.BooleanAlgebra
- Data.Bounded
- Data.Bounded.Generic
- Data.CommutativeRing
- Data.DivisionRing
- Data.Eq
- Data.Eq.Generic
- Data.EuclideanRing
- Data.Field
- Data.Function
- Data.Functor
- Data.Generic.Rep
- Data.HeytingAlgebra
- Data.HeytingAlgebra.Generic
- Data.Monoid
- Data.Monoid.Additive
- Data.Monoid.Conj
- Data.Monoid.Disj
- Data.Monoid.Dual
- Data.Monoid.Endo
- Data.Monoid.Generic
- Data.Monoid.Multiplicative
- Data.NaturalTransformation
- Data.Newtype
- Data.Ord
- Data.Ord.Down
- Data.Ord.Generic
- Data.Ord.Max
- Data.Ord.Min
- Data.Ordering
- Data.Ring
- Data.Ring.Generic
- Data.Semigroup
- Data.Semigroup.First
- Data.Semigroup.Generic
- Data.Semigroup.Last
- Data.Semiring
- Data.Semiring.Generic
- Data.Show
- Data.Show.Generic
- Data.Symbol
- Data.Unit
- Data.Void
- Foreign
- LocalDependency.Control.Alt
- LocalDependency.Control.Alternative
- LocalDependency.Control.Biapplicative
- LocalDependency.Control.Biapply
- LocalDependency.Control.Comonad
- LocalDependency.Control.Extend
- LocalDependency.Control.Lazy
- LocalDependency.Control.MonadPlus
- LocalDependency.Control.MonadZero
- LocalDependency.Control.Plus
- LocalDependency.Data.Bifoldable
- LocalDependency.Data.Bifunctor
- LocalDependency.Data.Bifunctor.Join
- LocalDependency.Data.Bitraversable
- LocalDependency.Data.Comparison
- LocalDependency.Data.Const
- LocalDependency.Data.Decidable
- LocalDependency.Data.Decide
- LocalDependency.Data.Distributive
- LocalDependency.Data.Divide
- LocalDependency.Data.Divisible
- LocalDependency.Data.Either
- LocalDependency.Data.Either.Inject
- LocalDependency.Data.Either.Nested
- LocalDependency.Data.Equivalence
- LocalDependency.Data.Exists
- LocalDependency.Data.Foldable
- LocalDependency.Data.FoldableWithIndex
- LocalDependency.Data.Functor.App
- LocalDependency.Data.Functor.Clown
- LocalDependency.Data.Functor.Compose
- LocalDependency.Data.Functor.Contravariant
- LocalDependency.Data.Functor.Coproduct
- LocalDependency.Data.Functor.Coproduct.Inject
- LocalDependency.Data.Functor.Coproduct.Nested
- LocalDependency.Data.Functor.Costar
- LocalDependency.Data.Functor.Flip
- LocalDependency.Data.Functor.Invariant
- LocalDependency.Data.Functor.Joker
- LocalDependency.Data.Functor.Product
- LocalDependency.Data.Functor.Product.Nested
- LocalDependency.Data.Functor.Product2
- LocalDependency.Data.FunctorWithIndex
- LocalDependency.Data.Identity
- LocalDependency.Data.Maybe
- LocalDependency.Data.Maybe.First
- LocalDependency.Data.Maybe.Last
- LocalDependency.Data.Monoid.Alternate
- LocalDependency.Data.Op
- LocalDependency.Data.Predicate
- LocalDependency.Data.Profunctor
- LocalDependency.Data.Profunctor.Choice
- LocalDependency.Data.Profunctor.Closed
- LocalDependency.Data.Profunctor.Cochoice
- LocalDependency.Data.Profunctor.Costrong
- LocalDependency.Data.Profunctor.Join
- LocalDependency.Data.Profunctor.Split
- LocalDependency.Data.Profunctor.Star
- LocalDependency.Data.Profunctor.Strong
- LocalDependency.Data.Semigroup.Foldable
- LocalDependency.Data.Semigroup.Traversable
- LocalDependency.Data.Traversable
- LocalDependency.Data.Traversable.Accum
- LocalDependency.Data.Traversable.Accum.Internal
- LocalDependency.Data.TraversableWithIndex
- LocalDependency.Data.Tuple
- LocalDependency.Data.Tuple.Nested
- LocalDependency.Effect
- LocalDependency.Safe.Coerce
- LocalDependency.Type.Equality
- LocalDependency.Unsafe.Coerce
- Prelude
- Prim
- Prim.Boolean
- Prim.Coerce
- Prim.Ordering
- Prim.Row
- Prim.RowList
- Prim.Symbol
- Prim.TypeError
- Record.Unsafe
- Safe.Coerce
- Test.Foreign
- Test.Main
- Test.MiraculixLite
- Test.MiraculixLite.Assertion
- Test.MiraculixLite.FFI
- Test.MiraculixLite.Summary
- Test.MiraculixLite.TestTree
- Test.MiraculixLite.Typo
- Type.Data.Row
- Type.Data.RowList
- Type.Proxy
- Unsafe.Coerce