Safe Haskell | None |
---|---|
Language | Haskell2010 |
witnesses a zero-cost conversion Sub
a ba -> b
.
Example
Think about the following code:
-- | A pair @(x::a, y::a)@, but guaranteed @x <= y@ newtype Range a = MkRange (a,a) getRange :: Range a -> (a,a) getRange = coerce mkRange :: Ord a => a -> a -> Range a mkRange x y = if x <= y then MkRange (x,y) else MkRange (y,x)
If you want to provide this type from a library you maintain,
you would want to keep Range
abstract from outside of the module.
A user may want to convert [Range a]
to [(a,a)]
without actually
traversing the list. This is possible if the user have access to the
internals, or you export a Coercion (Range a) (a,a)
value. But doing so
breaks the guarantee, because it also allows to use Coercible
in the other
direction, as in coerce (10,5) :: Range Int
.
By exporting only Sub (Range a) (a,a)
value from your module,
this user can get Sub [Range a] [(a,a)]
using mapR
,
without being able to make an invalid value.
Synopsis
- data Sub (a :: k) (b :: k)
- sub :: Coercible a b => Sub a b
- toSub :: Coercion a b -> Sub a b
- upcastWith :: Sub a b -> a -> b
- equiv :: Sub a b -> Sub b a -> Coercion a b
- gequiv :: Sub a b -> Sub b a -> (Coercible a b => r) -> r
- coercionIsSub :: Sub (Coercion a b) (Sub a b)
- instantiate :: forall j k (f :: j -> k) (g :: j -> k) (a :: j). Sub f g -> Sub (f a) (g a)
- mapR :: (forall x x'. Coercible x x' => Coercible (t x) (t x'), Functor t) => Sub a b -> Sub (t a) (t b)
- contramapR :: (forall x x'. Coercible x x' => Coercible (t x) (t x'), Contravariant t) => Sub a b -> Sub (t b) (t a)
- bimapR :: (forall x x' y y'. (Coercible x x', Coercible y y') => Coercible (t x y) (t x' y'), Bifunctor t) => Sub a a' -> Sub b b' -> Sub (t a b) (t a' b')
- prodR :: Sub a a' -> Sub b b' -> Sub (a, b) (a', b')
- prod3R :: Sub a a' -> Sub b b' -> Sub c c' -> Sub (a, b, c) (a', b', c')
- sumR :: Sub a a' -> Sub b b' -> Sub (Either a b) (Either a' b')
- dimapR :: (forall x x' y y'. (Coercible x x', Coercible y y') => Coercible (t x y) (t x' y'), Profunctor t) => Sub a a' -> Sub b b' -> Sub (t a' b) (t a b')
- arrR :: Sub a a' -> Sub b b' -> Sub (a' -> b) (a -> b')
Documentation
data Sub (a :: k) (b :: k) Source #
Sub
is a newtype wrapper around Coercion
, but made opaque to hide
the ability to coerce
into other direction.
This is convenient for newtype wrappers which give additional guarantees.
You can make Sub
witnesses by using combinators in this module, or the methods of
the
instance: Category
Subid
and (
..
)
Instances
Category (Sub :: k -> k -> Type) Source # | |
Coercible a b => Bounded (Sub a b) Source # | |
Coercible a b => Enum (Sub a b) Source # | |
Eq (Sub a b) Source # | |
Ord (Sub a b) Source # | |
Defined in Data.Type.Coercion.Sub.Internal | |
Coercible a b => Read (Sub a b) Source # | |
Show (Sub a b) Source # | |
upcastWith :: Sub a b -> a -> b Source #
Type-safe cast
instantiate :: forall j k (f :: j -> k) (g :: j -> k) (a :: j). Sub f g -> Sub (f a) (g a) Source #
For a Sub
relation between type constructors f
and g
,
create an instance of subtype relation Sub (f a) (g a)
for any type
parameter a
.
mapR :: (forall x x'. Coercible x x' => Coercible (t x) (t x'), Functor t) => Sub a b -> Sub (t a) (t b) Source #
Extend subtype relation covariantly.
contramapR :: (forall x x'. Coercible x x' => Coercible (t x) (t x'), Contravariant t) => Sub a b -> Sub (t b) (t a) Source #
Extend subtype relation contravariantly.
bimapR :: (forall x x' y y'. (Coercible x x', Coercible y y') => Coercible (t x y) (t x' y'), Bifunctor t) => Sub a a' -> Sub b b' -> Sub (t a b) (t a' b') Source #
Extend subtype relation over a Bifunctor
.
prodR :: Sub a a' -> Sub b b' -> Sub (a, b) (a', b') infixr 3 Source #
bimapR
specialized for the pair type '(a,b)'
prod3R :: Sub a a' -> Sub b b' -> Sub c c' -> Sub (a, b, c) (a', b', c') Source #
Extend subtype relation over the 3-tuple types '(a,b,c)'