// use std::{marker::PhantomData, ops::Deref}; use core::{marker::PhantomData}; use vars::UnCons; #[derive(Default)] struct HEmpty { _phantom: core::marker::PhantomData, } struct HCons>(L, R); struct HConsIterator> { pub current: V, pub rest: R, } trait HNext { type Next: HNext; fn value(&self) -> Option<&T>; fn next(self) -> Self::Next; } trait IntoHCons> { fn into_hcons(self) -> HCons; } trait Vars: HNext + IntoHCons { type Cons: HNext; } // impl > UnCons for HCons { // type NextIt = L; // type Tail = >::Next; // fn uncons(self) -> (Option, Self::Tail) { // (Some(self.0), self.1) // } // } // impl UnCons for HEmpty { // type Tail = HEmpty; // fn uncons(self) -> (Option, Self::Tail) { // (None, HEmpty { _phantom: PhantomData::default() }) // } // } // : IntoHCons>> + IntoHCons>>>{ // impl IntoHCons> for () { // fn into_hcons(self) -> HEmpty { // HEmpty { _phantom: std::marker::PhantomData::default() } // } // } impl IntoHCons> for (T,) { fn into_hcons(self) -> HCons> { HCons( self.0, HEmpty:: { _phantom: PhantomData::::default() }, ) } } impl IntoHCons>> for (T, T) { fn into_hcons(self) -> HCons>> { HCons( self.0, HCons( self.1, HEmpty:: { _phantom: PhantomData::::default() }, ), ) } } // impl > IntoHCons>> for G { // fn into_hcons(self) -> HCons>> { // HCons(self.0, HCons(self.1, HEmpty { _phantom: std::marker::PhantomData::default() })) // } // } // impl IntoHCons>>> for (T,T,T,) { // fn into_hcons(self) -> HCons>>> { // HCons(self.0, HCons(self.1, HCons(self.2, HEmpty { _phantom: std::marker::PhantomData::default() }))) // } // } // impl > IntoHCons>> for T { // fn into_hcons(self) -> HCons { // self.into_hcons() // } // } impl HNext for () { type Next = (); fn value(&self) -> Option<&T> { None } fn next(self) -> Self::Next { () } } impl HNext for (T,) { type Next = (); fn value(&self) -> Option<&T> { Some(&self.0) } fn next(self) -> Self::Next { () } } impl HNext for (T, T) { type Next = (T,); fn value(&self) -> Option<&T> { Some(&self.0) } fn next(self) -> (T,) { (self.1,) } } impl Vars for (T,) { type Cons = HEmpty; } impl Vars for (T, T) { type Cons = HCons>; } impl HNext for HEmpty { type Next = Self; fn value(&self) -> Option<&T> { None } fn next(self) -> Self::Next { self } } // impl Deref for HEmpty { // type Target = Option; // fn deref(&self) -> &Self::Target { // &None // } // } // impl > Deref for HCons { // type Target = Option; // fn deref(&self) -> &Self::Target { // &Some(self.0) // } // } impl> HNext for HCons { type Next = E; fn value(&self) -> Option<&T> { Some(&self.0) } fn next(self) -> Self::Next { self.1 } } // impl > IntoIterator for HCons { // type Item = V; // type IntoIter = HConsIterator; // fn into_iter(self) -> Self::IntoIter { // todo!() // } // } // impl > Iterator for HConsIterator { // type Item = V; // fn next(&mut self) -> Option { // self.rest = self.rest.next(); // Some(self.current) // } // } // impl From<(usize, usize,)> for HCons>> { // fn from(value: (usize, usize,)) -> Self { // let (v1, v2,) = value; // HCons(v1, HCons(v2, HEmpty { _phantom: PhantomData::default() })) // } // } // #[test] // fn tuple_into_hcons() { // fn auto_convert(v: HCons>>) { // } // auto_convert((1,2,).into()); // } #[test] fn hcons_init() { let h = HCons( 1, HCons( 3, HEmpty::default() ), ); assert_eq!(h.value(), Some(&1)); let h1 = h.next(); assert_eq!(h1.value(), Some(&3)); let h2 = h1.next(); assert_eq!(h2.value(), None); } #[test] fn vars() { fn variadic(v: impl Vars) { let h = v.into_hcons(); let v1 = h.value(); let h2 = h.next(); println!("{:?}", h2.value()); let h3 = h2.next(); println!("{:?}", h3.value()); let h4 = h3.next(); println!("{:?}", h4.value()); } variadic((1, 2)); } #[test] fn explicit_vs_implicit_type() { let h = (1,2,).into_hcons(); let n = h.value(); }