├── .gitignore ├── Cargo.toml └── src ├── gat.rs ├── gat ├── option.rs └── tree.rs ├── lib.rs ├── stable.rs ├── stable ├── iter.rs ├── option.rs ├── tree.rs └── validity.rs ├── tree.rs └── validity.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target* 2 | *.lock -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "type-families" 3 | version = "0.1.0" 4 | authors = ["RustyYato "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | ghost = '0.1' -------------------------------------------------------------------------------- /src/gat.rs: -------------------------------------------------------------------------------- 1 | pub mod option; 2 | pub mod tree; 3 | 4 | pub trait Family: Copy { 5 | type This; 6 | } 7 | 8 | pub trait Functor: Family { 9 | fn map B>(self, this: Self::This, f: F) -> Self::This; 10 | } 11 | 12 | pub trait Applicative: Functor { 13 | fn pure(self, value: A) -> Self::This; 14 | 15 | fn apply(self, a: Self::This, b: Self::This) -> Self::This 16 | where 17 | F: Fn(A) -> B, 18 | { 19 | self.lift_a2(a, b, move |q, r| q(r)) 20 | } 21 | 22 | fn lift_a2(self, a: Self::This, b: Self::This, f: F) -> Self::This 23 | where 24 | F: Fn(A, B) -> C; 25 | } 26 | 27 | pub trait Monad: Applicative { 28 | fn bind(self, a: Self::This, f: F) -> Self::This 29 | where 30 | F: Fn(A) -> Self::This; 31 | 32 | fn compose(self, f: F, g: G, a: A) -> Self::This 33 | where 34 | F: FnOnce(A) -> Self::This, 35 | G: Fn(B) -> Self::This, 36 | { 37 | self.bind(f(a), g) 38 | } 39 | 40 | fn join(self, outer: Self::This>) -> Self::This { self.bind(outer, core::convert::identity) } 41 | } 42 | 43 | pub trait Traverse: Family { 44 | fn traverse(self, app: F, this: Self::This, g: G) -> F::This> 45 | where 46 | G: Fn(A) -> F::This + Copy; 47 | } 48 | -------------------------------------------------------------------------------- /src/gat/option.rs: -------------------------------------------------------------------------------- 1 | use super::{Applicative, Family, Functor, Monad, Traverse}; 2 | use crate::OptionFamily; 3 | 4 | impl Family for OptionFamily { 5 | type This = Option; 6 | } 7 | 8 | impl Functor for OptionFamily { 9 | fn map B>(self, this: Self::This, f: F) -> Self::This { this.map(f) } 10 | } 11 | 12 | impl Applicative for OptionFamily { 13 | fn pure(self, value: A) -> Self::This { Some(value) } 14 | 15 | fn lift_a2(self, a: Self::This, b: Self::This, f: F) -> Self::This 16 | where 17 | F: Fn(A, B) -> C, 18 | { 19 | Some(f(a?, b?)) 20 | } 21 | } 22 | 23 | impl Monad for OptionFamily { 24 | fn bind(self, a: Self::This, f: F) -> Self::This 25 | where 26 | F: Fn(A) -> Self::This, 27 | { 28 | a.and_then(f) 29 | } 30 | } 31 | 32 | impl Traverse for OptionFamily { 33 | fn traverse(self, app: F, this: Self::This, g: G) -> F::This> 34 | where 35 | G: Fn(A) -> F::This, 36 | { 37 | match this { 38 | None => app.pure(None), 39 | Some(x) => app.map(g(x), Some), 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/gat/tree.rs: -------------------------------------------------------------------------------- 1 | use super::{Applicative, Family, Functor, Monad, Traverse}; 2 | use crate::tree::{Tree, TreeFamily}; 3 | 4 | impl Family for TreeFamily { 5 | type This = Tree; 6 | } 7 | 8 | impl Functor for TreeFamily { 9 | fn map B>(self, this: Self::This, f: F) -> Self::This { 10 | match this { 11 | Tree::Tip(value) => Tree::Tip(f(value)), 12 | Tree::Node(inner) => { 13 | let [left, right] = *inner; 14 | let left = self.map(left, &f); 15 | let right = self.map(right, f); 16 | Tree::Node(Box::new([left, right])) 17 | } 18 | } 19 | } 20 | } 21 | 22 | impl Applicative for TreeFamily { 23 | fn pure(self, value: A) -> Self::This { Tree::Tip(value) } 24 | 25 | fn lift_a2(self, a: Self::This, b: Self::This, f: F) -> Self::This 26 | where 27 | F: Fn(A, B) -> C, 28 | { 29 | match (a, b) { 30 | (Tree::Tip(a), Tree::Tip(b)) => Tree::Tip(f(a, b)), 31 | (Tree::Node(a), Tree::Node(b)) => { 32 | let [al, ar] = *a; 33 | let [bl, br] = *b; 34 | Tree::Node(Box::new([self.lift_a2(al, bl, &f), self.lift_a2(ar, br, f)])) 35 | } 36 | (a @ Tree::Tip(_), Tree::Node(b)) => { 37 | let [l, _] = *b; 38 | self.lift_a2(a, l, f) 39 | } 40 | (Tree::Node(a), b @ Tree::Tip(_)) => { 41 | let [_, r] = *a; 42 | self.lift_a2(r, b, f) 43 | } 44 | } 45 | } 46 | } 47 | 48 | impl Monad for TreeFamily { 49 | fn bind(self, a: Self::This, f: F) -> Self::This 50 | where 51 | F: Fn(A) -> Self::This, 52 | { 53 | match a { 54 | Tree::Tip(value) => f(value), 55 | Tree::Node(a) => { 56 | let [l, r] = *a; 57 | let l: Self::This = self.bind(l, &f); 58 | let r: Self::This = self.bind(r, &f); 59 | Tree::Node(Box::new([l, r])) 60 | } 61 | } 62 | } 63 | } 64 | 65 | impl Traverse for TreeFamily { 66 | fn traverse(self, app: F, this: Self::This, g: G) -> F::This> 67 | where 68 | G: Fn(A) -> F::This + Copy, 69 | { 70 | match this { 71 | Tree::Tip(a) => app.map(g(a), Tree::Tip), 72 | Tree::Node(node) => { 73 | let [l, r] = *node; 74 | let l: F::This> = self.traverse(app, l, g); 75 | let r: F::This> = self.traverse(app, r, g); 76 | 77 | app.lift_a2(l, r, |l, r| Tree::Node(Box::new([l, r]))) 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(generic_associated_types)] 2 | #![allow(incomplete_features)] 3 | 4 | pub mod tree; 5 | pub mod validity; 6 | 7 | mod gat; 8 | mod stable; 9 | 10 | #[derive(Clone, Copy)] 11 | pub struct OptionFamily; 12 | 13 | #[test] 14 | fn foo() { 15 | use self::tree::*; 16 | use stable::*; 17 | 18 | let tr: Tree = tree! { 19 | node { 20 | node { 21 | tip = 1, 22 | node { 23 | tip = 1, 24 | tip = 2, 25 | } 26 | }, 27 | node { 28 | tip = 3, 29 | tip = 4, 30 | } 31 | } 32 | }; 33 | 34 | TreeFamily.map(tr, |x| x + 1); 35 | 36 | let tr: Tree = tree! { 37 | node { 38 | node { 39 | tip = 1, 40 | node { 41 | tip = 1, 42 | tip = 2, 43 | } 44 | }, 45 | node { 46 | tip = 3, 47 | tip = 4, 48 | } 49 | } 50 | }; 51 | 52 | let x: Option> = TreeFamily.traverse(OptionFamily, tr, |x| x.checked_sub(1)); 53 | 54 | assert_eq!( 55 | x, 56 | Some(tree! { 57 | node { 58 | node { 59 | tip = 0, 60 | node { 61 | tip = 0, 62 | tip = 1, 63 | } 64 | }, 65 | node { 66 | tip = 2, 67 | tip = 3, 68 | } 69 | } 70 | }) 71 | ); 72 | } 73 | -------------------------------------------------------------------------------- /src/stable.rs: -------------------------------------------------------------------------------- 1 | pub mod iter; 2 | pub mod option; 3 | pub mod tree; 4 | pub mod validity; 5 | 6 | pub type This = >::This; 7 | pub trait Family: Copy { 8 | type This; 9 | } 10 | 11 | pub trait Functor: Family + Family { 12 | fn map B + Copy>(self, this: This, f: F) -> This; 13 | } 14 | 15 | pub trait Pure: Family { 16 | fn pure(self, value: A) -> This; 17 | } 18 | 19 | pub trait Applicative: Functor + Pure + Pure { 20 | fn apply(self, a: This, b: This) -> This 21 | where 22 | F: Fn(A) -> B, 23 | Self: Applicative, 24 | { 25 | self.lift_a2(a, b, move |q: F, r| q(r)) 26 | } 27 | 28 | fn lift_a2(self, a: This, b: This, f: F) -> This 29 | where 30 | F: Fn(A, B) -> C, 31 | Self: Pure; 32 | } 33 | 34 | #[macro_export(local_inner_macros)] 35 | macro_rules! parse_do_notation { 36 | ( 37 | $monad:expr => 38 | ) => {}; 39 | ( 40 | $monad:expr => pure $value:expr 41 | ) => { 42 | $crate::stable::Pure::pure($monad, $value) 43 | }; 44 | ( 45 | $monad:expr => $value:expr; $($rest:tt)* 46 | ) => {{ 47 | $value; 48 | parse_do_notation!($monad => $($rest)*) 49 | }}; 50 | ( 51 | $monad:expr => $value:stmt; $($rest:tt)* 52 | ) => {{ 53 | $value 54 | parse_do_notation!($monad => $($rest)*) 55 | }}; 56 | ( 57 | $monad:expr => 58 | $pat:pat => $value:expr; 59 | $($rest:tt)* 60 | ) => { 61 | $crate::stable::Monad::bind( 62 | $monad, 63 | $value, 64 | move |$pat| parse_do_notation!($monad => $($rest)*) 65 | ) 66 | }; 67 | } 68 | 69 | #[macro_export(local_inner_macros)] 70 | macro_rules! do_notation { 71 | ( 72 | $monad:expr => { $($expr:tt)* } 73 | ) => { 74 | parse_do_notation! { 75 | $monad => $($expr)* 76 | } 77 | }; 78 | } 79 | 80 | pub trait Monad: Applicative { 81 | fn bind(self, a: This, f: F) -> This 82 | where 83 | F: Fn(A) -> This; 84 | 85 | fn compose(self, f: F, g: G, a: A) -> This 86 | where 87 | F: FnOnce(A) -> This, 88 | G: Fn(B) -> This, 89 | Self: Monad, 90 | { 91 | self.bind(f(a), g) 92 | } 93 | } 94 | 95 | pub trait Traverse + Family>>: Family + Family { 96 | fn traverse(self, app: F, this: This, g: G) -> This> 97 | where 98 | G: Fn(A) -> This + Copy; 99 | } 100 | 101 | pub trait SemiGroup { 102 | fn append(self, rhs: Self) -> Self; 103 | } 104 | 105 | impl SemiGroup for Vec { 106 | fn append(mut self, rhs: Self) -> Self { 107 | self.extend(rhs); 108 | self 109 | } 110 | } 111 | 112 | impl SemiGroup for String { 113 | fn append(mut self, rhs: Self) -> Self { 114 | self.push_str(&rhs); 115 | self 116 | } 117 | } 118 | 119 | impl SemiGroup for () { 120 | fn append(self, (): Self) -> Self {} 121 | } 122 | -------------------------------------------------------------------------------- /src/stable/iter.rs: -------------------------------------------------------------------------------- 1 | use super::*; 2 | 3 | #[derive(Clone, Copy)] 4 | pub struct Iter(pub T); 5 | 6 | impl, A> Family for Iter { 7 | type This = T::This; 8 | } 9 | 10 | impl + Family, F, A, B> Traverse for Iter 11 | where 12 | F: Applicative>, 13 | This: IntoIterator, 14 | This: Extend + Default, 15 | { 16 | fn traverse(self, app: F, this: This, g: G) -> This> 17 | where 18 | G: Fn(A) -> This + Copy, 19 | { 20 | let this_b = This::::default(); 21 | let mut f_this_b = app.pure(this_b); 22 | 23 | for f_b in this.into_iter().map(g) { 24 | f_this_b = app.lift_a2(f_b, f_this_b, move |b, mut this_b| { 25 | this_b.extend(Some(b)); 26 | this_b 27 | }); 28 | } 29 | 30 | f_this_b 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/stable/option.rs: -------------------------------------------------------------------------------- 1 | use super::{Applicative, Family, Functor, Monad, Pure, This}; 2 | use crate::OptionFamily; 3 | 4 | impl Family for OptionFamily { 5 | type This = Option; 6 | } 7 | 8 | impl Functor for OptionFamily { 9 | fn map B>(self, this: This, f: F) -> This { this.map(f) } 10 | } 11 | 12 | impl Pure for OptionFamily { 13 | fn pure(self, value: A) -> This { Some(value) } 14 | } 15 | 16 | impl Applicative for OptionFamily { 17 | fn lift_a2(self, a: This, b: This, f: F) -> This 18 | where 19 | F: Fn(A, B) -> C, 20 | { 21 | Some(f(a?, b?)) 22 | } 23 | } 24 | 25 | impl Monad for OptionFamily { 26 | fn bind(self, a: This, f: F) -> This 27 | where 28 | F: Fn(A) -> This, 29 | { 30 | a.and_then(f) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/stable/tree.rs: -------------------------------------------------------------------------------- 1 | use super::{Applicative, Family, Functor, Monad, Pure, This, Traverse}; 2 | use crate::tree::{Tree, TreeFamily}; 3 | 4 | impl Family for TreeFamily { 5 | type This = Tree; 6 | } 7 | 8 | impl Functor for TreeFamily { 9 | fn map B + Copy>(self, this: This, f: F) -> This { 10 | match this { 11 | Tree::Tip(value) => Tree::Tip(f(value)), 12 | Tree::Node(inner) => { 13 | let [left, right] = *inner; 14 | let left = self.map(left, f); 15 | let right = self.map(right, f); 16 | Tree::Node(Box::new([left, right])) 17 | } 18 | } 19 | } 20 | } 21 | 22 | impl Pure for TreeFamily { 23 | fn pure(self, value: A) -> This { Tree::Tip(value) } 24 | } 25 | 26 | impl Applicative for TreeFamily { 27 | fn lift_a2(self, a: This, b: This, f: F) -> This 28 | where 29 | F: Fn(A, B) -> C, 30 | { 31 | match (a, b) { 32 | (Tree::Tip(a), Tree::Tip(b)) => Tree::Tip(f(a, b)), 33 | (Tree::Node(a), Tree::Node(b)) => { 34 | let [al, ar] = *a; 35 | let [bl, br] = *b; 36 | Tree::Node(Box::new([self.lift_a2(al, bl, &f), self.lift_a2(ar, br, f)])) 37 | } 38 | (a @ Tree::Tip(_), Tree::Node(b)) => { 39 | let [l, _] = *b; 40 | self.lift_a2(a, l, f) 41 | } 42 | (Tree::Node(a), b @ Tree::Tip(_)) => { 43 | let [_, r] = *a; 44 | self.lift_a2(r, b, f) 45 | } 46 | } 47 | } 48 | } 49 | 50 | impl Monad for TreeFamily { 51 | fn bind(self, a: This, f: F) -> This 52 | where 53 | F: Fn(A) -> This, 54 | { 55 | match a { 56 | Tree::Tip(value) => f(value), 57 | Tree::Node(a) => { 58 | let [l, r] = *a; 59 | let l: This = self.bind(l, &f); 60 | let r: This = self.bind(r, &f); 61 | Tree::Node(Box::new([l, r])) 62 | } 63 | } 64 | } 65 | } 66 | 67 | impl Traverse for TreeFamily 68 | where 69 | F: Applicative, This> + Functor>, 70 | { 71 | fn traverse(self, app: F, this: This, g: G) -> This> 72 | where 73 | G: Fn(A) -> This + Copy, 74 | { 75 | match this { 76 | Tree::Tip(a) => app.map(g(a), Tree::Tip), 77 | Tree::Node(node) => { 78 | let [l, r] = *node; 79 | let l: This> = self.traverse(app, l, g); 80 | let r: This> = self.traverse(app, r, g); 81 | 82 | app.lift_a2(l, r, |l, r| Tree::Node(Box::new([l, r]))) 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/stable/validity.rs: -------------------------------------------------------------------------------- 1 | use super::*; 2 | use crate::validity::Validity; 3 | 4 | use ghost::phantom; 5 | 6 | #[phantom] 7 | #[derive(Debug, Clone, Copy)] 8 | pub struct ValidityFamily; 9 | 10 | impl Family for ValidityFamily { 11 | type This = Validity; 12 | } 13 | 14 | impl Functor for ValidityFamily { 15 | fn map B>(self, this: This, f: F) -> This { 16 | match this { 17 | Validity::Valid(valid) => Validity::Valid(f(valid)), 18 | Validity::Invalid(invalid) => Validity::Invalid(invalid), 19 | } 20 | } 21 | } 22 | 23 | impl Pure for ValidityFamily { 24 | fn pure(self, value: A) -> This { Validity::Valid(value) } 25 | } 26 | 27 | impl Applicative for ValidityFamily { 28 | fn lift_a2(self, a: This, b: This, f: F) -> This 29 | where 30 | F: Fn(A, B) -> C, 31 | { 32 | match (a, b) { 33 | (Validity::Valid(a), Validity::Valid(b)) => Validity::Valid(f(a, b)), 34 | (Validity::Invalid(a), Validity::Invalid(b)) => Validity::Invalid(a.append(b)), 35 | (Validity::Invalid(x), _) | (_, Validity::Invalid(x)) => Validity::Invalid(x), 36 | } 37 | } 38 | } 39 | 40 | impl Monad for ValidityFamily { 41 | fn bind(self, a: This, f: F) -> This 42 | where 43 | F: Fn(A) -> This, 44 | { 45 | match a { 46 | Validity::Valid(value) => f(value), 47 | Validity::Invalid(error) => Validity::Invalid(error), 48 | } 49 | } 50 | } 51 | 52 | impl Traverse for ValidityFamily 53 | where 54 | F: Applicative>, 55 | { 56 | fn traverse(self, app: F, this: This, g: G) -> This> 57 | where 58 | G: Fn(A) -> This + Copy, 59 | { 60 | match this { 61 | Validity::Valid(value) => app.map(g(value), Validity::Valid), 62 | Validity::Invalid(error) => app.pure(Validity::Invalid(error)), 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/tree.rs: -------------------------------------------------------------------------------- 1 | #[macro_export(local_inner_macros)] 2 | macro_rules! node { 3 | (@first node { $($inner:tt)* }, $($rest:tt)*) => { 4 | node!{ 5 | @second [tree!(node { $($inner)* })] $($rest)* 6 | } 7 | }; 8 | (@first tip = $value:expr, $($rest:tt)*) => { 9 | node!{ 10 | @second [$crate::tree::Tree::Tip($value)] $($rest)* 11 | } 12 | }; 13 | (@second [$first:expr] node { $($inner:tt)* } $(,)?) => { 14 | $crate::tree::Tree::Node(Box::new([ 15 | $first, 16 | tree!(node { $($inner)* }), 17 | ])) 18 | }; 19 | (@second [$first:expr] tip = $value:expr $(,)?) => { 20 | $crate::tree::Tree::Node(Box::new([ 21 | $first, 22 | $crate::tree::Tree::Tip($value), 23 | ])) 24 | }; 25 | } 26 | 27 | #[macro_export(local_inner_macros)] 28 | macro_rules! tree { 29 | (node { $($inner:tt)* }) => { 30 | node!(@first $($inner)*) 31 | }; 32 | (tip = $value:expr) => { 33 | $crate::tree::Tree::Tip($value) 34 | }; 35 | } 36 | 37 | #[derive(Debug, PartialEq, Eq)] 38 | pub enum Tree { 39 | Tip(A), 40 | Node(Box<[Tree; 2]>), 41 | } 42 | 43 | #[derive(Clone, Copy)] 44 | pub struct TreeFamily; 45 | -------------------------------------------------------------------------------- /src/validity.rs: -------------------------------------------------------------------------------- 1 | pub enum Validity { 2 | Valid(T), 3 | Invalid(E), 4 | } 5 | --------------------------------------------------------------------------------