pub trait RevTypeFn<Ret: ?Sized>: TypeFn<Self::Arg, Output = Ret> {
type Arg: ?Sized;
}
Expand description
The inverse of TypeFn
,
for getting the argument of a TypeFn
from its return value.
§Properties
These are properties about RevTypeFn
that users can rely on.
For any given F: RevTypeFn<R> + RevTypeFn<O>
these hold:
-
If
R == O
, thenUncallFn<F, R> == UncallFn<F, O>
-
If
R != O
, thenUncallFn<F, R> != UncallFn<F, O>
Disclaimer: this trait does not by itself ensure that a function is
injective,
since RevTypeFn<Ret>
can’t know if Self::Arg
is the only argument
that could produce Ret
.
§Examples
§Macro-based impl
use std::ops::Range;
use typewit::{RevTypeFn, UncallFn};
let array = [3usize, 5];
// Getting the argument of `ArrayFn` from its return value
let value: UncallFn<ArrayFn<2>, [usize; 2]> = array[0];
assert_eq!(value, 3usize);
typewit::inj_type_fn!{
struct ArrayFn<const N: usize>;
impl<T> T => [T; N]
}
§Manual impl
use std::ops::Range;
use typewit::{CallInjFn, RevTypeFn, TypeFn, UncallFn};
let array = [3usize, 5];
// Getting the argument of `ArrayFn` from its return value
let value: UncallFn<ArrayFn<2>, [usize; 2]> = array[0];
assert_eq!(value, 3usize);
struct ArrayFn<const N: usize>;
impl<T, const N: usize> TypeFn<T> for ArrayFn<N> {
type Output = [T; N];
// Ensures that this impl of `TypeFn` for `ArrayFn` is injective.
const TYPE_FN_ASSERTS: () = { let _: CallInjFn<Self, T>; };
}
impl<T, const N: usize> RevTypeFn<[T; N]> for ArrayFn<N> {
type Arg = T;
}
§Non-injective function
As mentioned above, this trait doesn’t make a function injective.
In the example below, NonInjective
isn’t injective, because it maps different
arguments to the same return value:
use typewit::{CallFn, RevTypeFn, TypeFn, UncallFn};
let _: CallFn<NonInjective, Vec<u8>> = 3u8;
let _: CallFn<NonInjective, String> = 5u8;
let _: UncallFn<NonInjective, u8> = ();
struct NonInjective;
impl<T> TypeFn<T> for NonInjective {
type Output = u8;
}
impl RevTypeFn<u8> for NonInjective {
type Arg = ();
}
Required Associated Types§
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.