Safe Haskell | None |
---|---|
Language | Haskell2010 |
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
Sub a b
witnesses a zero-cost conversion a -> b
.
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.
As an 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.
An 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.
data Sub (a :: k) (b :: k) Source #
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 # | |
sub :: Coercible a b => Sub a b Source #
Make a witness for type-safe casting which respects direction.
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)'