1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! Implementation of higher-kinded types in Rust using associated types.
//!
//! This is a variation of
//! [Edmund Smith's](https://gist.github.com/edmundsmith/855fcf0cb35dd467c29a9350481f0ecf)
//! method where instead of unplugging and plugging generic arguments between
//! fully defined types (i.e. `Vec<X>` <-> `Vec<Y>`), higher-kinded types are
//! represented as structs that implement either `PlugLifetime` or
//! `PlugType`. We refer to these structs as *HKT forms*. To be explicit,
//! sometimes we refer to types that are not HKT forms as *concrete types* or
//! `H0` types.
//!
//! For example, `H1Vec`, the higher-kinded form of `Vec`, implements
//! `PlugType`. Then, to get the concrete `Vec<T>` for a type `T`:
//!
//! ```text
//! <H1Vec as PlugType<T>>::T
//! ```
//!
//! # Conventions for HTK Forms
//!
//! As a convention, all HKT forms must be zero-sized structs, only implement
//! `PlugLifetime` or `PlugType` and respect the following naming convention:
//!
//! ```text
//! H<n><t>
//! ```
//!
//! Where `<n>` is the number of lifetype + type arguments left to be filled,
//! also referred to as slots, and `<t>` is the name of the concrete type. For
//! example, `Cow` has two HKT forms:
//!
//! - `H2Cow` which implements `PlugLifetime`, yielding `H1Cow<'a>`
//! - `H1Cow<'a>` which implements `PlugType`, yielding a concrete `Cow<'a, T>`
//!
//! The generic arguments are always filled from left to right, lifetimes
//! first. In some cases it might be useful to plug those out of order. In
//! those cases we prepend something descriptive to the type name. See for
//! example [`TypedH1Reference`](../reference/struct.TypedH1Reference.html).
//!
//! # HKT-Compatible Concrete Types
//!
//! The `PlugLifetime` and `PlugType` may also be implemented for concrete
//! types, in which case `Type` is just itself. This is useful to implement
//! streaming iterators and similar constructs. [`H0`](struct.H0.html) is a
//! type wrapper for exactly this case.
use PhantomData;
/// Trait enabling a lifetime to plugged to HKT forms.
/// Trait enabling a type to be plugged to HKT forms.
/// Type-level wrapper that yields `T` unmodified when `PlugLifetime` or
/// `PlugType` are applied.
;