Safe Haskell | None |
---|---|
Language | Haskell2010 |
Coerce
Synopsis
- class a ~R# b => Coercible (a :: k0) (b :: k0)
- coerce :: Coercible a b => a -> b
- data Coercion (a :: k) (b :: k) :: forall k. k -> k -> * where
- coerceWith :: Coercion a b -> a -> b
- gcoerceWith :: Coercion a b -> (Coercible a b -> r) -> r
- sym :: Coercion a b -> Coercion b a
- trans :: Coercion a b -> Coercion b c -> Coercion a c
- repr :: (a :~: b) -> Coercion a b
- class TestCoercion (f :: k -> *) where
Coercible
class a ~R# b => Coercible (a :: k0) (b :: k0) #
Coercible
is a two-parameter class that has instances for types a
and b
if
the compiler can infer that they have the same representation. This class
does not have regular instances; instead they are created on-the-fly during
type-checking. Trying to manually declare an instance of Coercible
is an error.
Nevertheless one can pretend that the following three kinds of instances exist. First, as a trivial base-case:
instance Coercible a a
Furthermore, for every type constructor there is
an instance that allows to coerce under the type constructor. For
example, let D
be a prototypical type constructor (data
or
newtype
) with three type arguments, which have roles nominal
,
representational
resp. phantom
. Then there is an instance of
the form
instance Coercible b b' => Coercible (D a b c) (D a b' c')
Note that the nominal
type arguments are equal, the
representational
type arguments can differ, but need to have a
Coercible
instance themself, and the phantom
type arguments can be
changed arbitrarily.
The third kind of instance exists for every newtype NT = MkNT T
and
comes in two variants, namely
instance Coercible a T => Coercible a NT
instance Coercible T b => Coercible NT b
This instance is only usable if the constructor MkNT
is in scope.
If, as a library author of a type constructor like Set a
, you
want to prevent a user of your module to write
coerce :: Set T -> Set NT
,
you need to set the role of Set
's type parameter to nominal
,
by writing
type role Set nominal
For more details about this feature, please refer to Safe Coercions by Joachim Breitner, Richard A. Eisenberg, Simon Peyton Jones and Stephanie Weirich.
Since: ghc-prim-4.7.0.0
coerce :: Coercible a b => a -> b #
The function coerce
allows you to safely convert between values of
types that have the same representation with no run-time overhead. In the
simplest case you can use it instead of a newtype constructor, to go from
the newtype's concrete type to the abstract type. But it also works in
more complicated settings, e.g. converting a list of newtypes to a list of
concrete types.
Coercion
data Coercion (a :: k) (b :: k) :: forall k. k -> k -> * where #
Representational equality. If Coercion a b
is inhabited by some terminating
value, then the type a
has the same underlying representation as the type b
.
To use this equality in practice, pattern-match on the Coercion a b
to get out
the Coercible a b
instance, and then use coerce
to apply it.
Since: base-4.7.0.0
Instances
Category (Coercion :: k -> k -> *) | Since: base-4.7.0.0 |
Groupoid (Coercion :: k -> k -> *) | |
Defined in Data.Groupoid | |
Semigroupoid (Coercion :: k -> k -> *) | |
TestCoercion (Coercion a :: k -> *) | Since: base-4.7.0.0 |
Defined in Data.Type.Coercion | |
Coercible a b => Bounded (Coercion a b) | Since: base-4.7.0.0 |
Coercible a b => Enum (Coercion a b) | Since: base-4.7.0.0 |
Defined in Data.Type.Coercion Methods succ :: Coercion a b -> Coercion a b # pred :: Coercion a b -> Coercion a b # toEnum :: Int -> Coercion a b # fromEnum :: Coercion a b -> Int # enumFrom :: Coercion a b -> [Coercion a b] # enumFromThen :: Coercion a b -> Coercion a b -> [Coercion a b] # enumFromTo :: Coercion a b -> Coercion a b -> [Coercion a b] # enumFromThenTo :: Coercion a b -> Coercion a b -> Coercion a b -> [Coercion a b] # | |
Eq (Coercion a b) | |
(Coercible a b, Data a, Data b) => Data (Coercion a b) | Since: base-4.7.0.0 |
Defined in Data.Data Methods gfoldl :: (forall d b0. Data d => c (d -> b0) -> d -> c b0) -> (forall g. g -> c g) -> Coercion a b -> c (Coercion a b) # gunfold :: (forall b0 r. Data b0 => c (b0 -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Coercion a b) # toConstr :: Coercion a b -> Constr # dataTypeOf :: Coercion a b -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Coercion a b)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Coercion a b)) # gmapT :: (forall b0. Data b0 => b0 -> b0) -> Coercion a b -> Coercion a b # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Coercion a b -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Coercion a b -> r # gmapQ :: (forall d. Data d => d -> u) -> Coercion a b -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Coercion a b -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Coercion a b -> m (Coercion a b) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Coercion a b -> m (Coercion a b) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Coercion a b -> m (Coercion a b) # | |
Ord (Coercion a b) | |
Defined in Data.Type.Coercion | |
Coercible a b => Read (Coercion a b) | Since: base-4.7.0.0 |
Show (Coercion a b) | |
Coercible a b => Upper (Coercion a b) | |
Defined in Data.Semilattice.Upper Methods upperBound :: Coercion a b # | |
Coercible a b => Lower (Coercion a b) | |
Defined in Data.Semilattice.Lower Methods lowerBound :: Coercion a b # |
coerceWith :: Coercion a b -> a -> b #
Type-safe cast, using representational equality
gcoerceWith :: Coercion a b -> (Coercible a b -> r) -> r #
Generalized form of type-safe cast using representational equality
Since: base-4.10.0.0
repr :: (a :~: b) -> Coercion a b #
Convert propositional (nominal) equality to representational equality
class TestCoercion (f :: k -> *) where #
This class contains types where you can learn the equality of two types from information contained in terms. Typically, only singleton types should inhabit this class.
Minimal complete definition
Methods
testCoercion :: f a -> f b -> Maybe (Coercion a b) #
Conditionally prove the representational equality of a
and b
.
Instances
TestCoercion (Coercion a :: k -> *) | Since: base-4.7.0.0 |
Defined in Data.Type.Coercion | |
TestCoercion ((:~:) a :: k -> *) | Since: base-4.7.0.0 |
Defined in Data.Type.Coercion | |
TestCoercion ((:~~:) a :: k -> *) | Since: base-4.10.0.0 |
Defined in Data.Type.Coercion |