Advertisement
phicr

list_map.rs

Nov 27th, 2023 (edited)
1,045
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.77 KB | None | 0 0
  1. use super::*;
  2. pub use value_struct::*;
  3.  
  4. pub trait ListMap<S>: List {
  5.   type Result<U: 'static>: List;
  6. }
  7.  
  8. impl<S> ListMap<S> for Empty {
  9.  type Result<U: 'static> = Self;
  10. }
  11.  
  12. impl<S, T: 'static> ListMap<S> for TypedEmpty<T> {
  13.  type Result<U: 'static> = TypedEmpty<U>;
  14. }
  15.  
  16. impl<S> ListMap<S> for ListError {
  17.   type Result<U: 'static> = Self;
  18. }
  19.  
  20. impl<S, T: 'static> ListMap<S> for TypedListError<T> {
  21.   type Result<U: 'static> = TypedListError<U>;
  22. }
  23.  
  24. pub macro let_list_map {
  25.  ($(type $name: ident = ($($t:tt)*)($L: ty);)*) => {
  26.    $(
  27.      let_list_map_sing! {
  28.        type $name = ($($t)*)($L);
  29.      }
  30.    )*
  31.  }
  32. }
  33.  
  34. pub macro let_list_map_sing {
  35.  (type $name: ident = (|$arg: ident| $x: expr)($L: ty);) => {
  36.    pub struct H;
  37.  
  38.    forall_types! {
  39.      all {
  40.        type U #+ #T =
  41.          type_of!(default_value!($L, ftype!(#T)));
  42.  
  43.        type T #+ #T =
  44.          type_of!((&const |$arg: U #+ #T| $x)
  45.            (default_value!($L, ftype!(#T))));
  46.  
  47.        pub const fn f #+ #T(x: ftype!(#T)) -> T #+ #T {
  48.          (&const |$arg: U #+ #T| $x)(convert_value!($L, ftype!(#T), x))
  49.        }
  50.  
  51.        impl<const T: ftype!(#T), N: ListMap<H>>
  52.        ListMap<H> for ListNode<ftype!(#T), self::value_struct![#T,T], N>
  53.        where as_value_spec![T #+ #T; {f #+ #T(T)}]: {
  54.          type Result<U: 'static> =
  55.             ListNode<
  56.              T #+ #T,
  57.              as_value_spec![T #+ #T; {f #+ #T(T)}],
  58.              <N as ListMap<H>>::Result<T #+ #T>>;
  59.         }
  60.       }
  61.     }
  62.     type $name = <$L as ListMap<H>>::Result<()>;
  63.   },
  64.   (type $name: ident = (|_| $x: expr)($L: ty);) => {
  65.     pub struct H;
  66.  
  67.     type T = type_of!((&const |_| $x)(0));
  68.  
  69.     #[allow(unused_braces)]
  70.     pub const fn f(_: i32) -> T {
  71.       $x
  72.     }
  73.  
  74.     impl<S, E: Value<ValueType=S>, N: ListMap<H>>
  75.     ListMap<H> for ListNode<S, E, N>
  76.     where as_value_spec![T; {f(0)}]: {
  77.       type Result<U: 'static> =
  78.        ListNode<
  79.          T,
  80.          as_value_spec![T; {f(0)}],
  81.          <N as ListMap<H>>::Result<T>>;
  82.    }
  83.    type $name = <$L as ListMap<H>>::Result<()>;
  84.  },
  85.  (type $name: ident = (|$arg: ident: $T: ty| $x: expr)($L: ty);) => {
  86.    pub struct H;
  87.  
  88.    type T = type_of!((&const |$arg: ftype!($T)| $x)
  89.            (default_value!($L, ftype!($T))));
  90.  
  91.    #[allow(unused_braces)]
  92.    pub const fn f(x: ftype!($T)) -> T {
  93.      (&const |$arg: ftype!($T)| -> T { $x } )(x)
  94.    }
  95.  
  96.    impl<const V: ftype!($T), N: ListMap<H>>
  97.    ListMap<H> for ListNode<ftype!($T), value_struct![$T, V], N>
  98.    where as_value_spec![T; {f(V)}]: {
  99.      type Result<U: 'static> =
  100.         ListNode<
  101.           T,
  102.           as_value_spec![T; {f(V)}],
  103.           <N as ListMap<H>>::Result<T>>;
  104.     }
  105.     type $name = <$L as ListMap<H>>::Result<()>;
  106.   }
  107. }
  108.  
  109.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement