Created
January 18, 2026 23:44
-
-
Save joonazan/b24aea422ab540f10a087e0f76f9db30 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| struct One; | |
| struct Succ<T>(T); | |
| trait Pos { | |
| type Add<Other: Pos>: Pos; | |
| } | |
| impl Pos for One { | |
| type Add<Other: Pos> = Succ<Other>; | |
| } | |
| impl<T: Pos> Pos for Succ<T> { | |
| type Add<Other: Pos> = Succ<T::Add<Other>>; | |
| } | |
| struct Stack<N, I>(N, I); | |
| struct EmptyStack; | |
| struct IronOre; | |
| struct Iron; | |
| struct CopperOre; | |
| struct Copper; | |
| struct Furnace<In, Out, Time>(In, Out, Time); | |
| trait FurnaceInsert<S> { | |
| type Ret; | |
| fn insert(self, stack: S) -> Self::Ret; | |
| } | |
| impl<N, I, Out, T> FurnaceInsert<Stack<N, I>> for Furnace<EmptyStack, Out, T> { | |
| type Ret = Furnace<Stack<N, I>, Out, T>; | |
| fn insert(self, _: Stack<N, I>) -> Self::Ret { | |
| todo!() | |
| } | |
| } | |
| impl<I, N: Pos, N2: Pos, Out, T> FurnaceInsert<Stack<N, I>> for Furnace<Stack<N2, I>, Out, T> { | |
| type Ret = Furnace<Stack<N::Add<N2>, I>, Out, T>; | |
| fn insert(self, _: Stack<N, I>) -> Self::Ret { | |
| todo!() | |
| } | |
| } | |
| trait FurnaceTick { | |
| type Next; | |
| } | |
| impl<O, T: Pos> FurnaceTick for Furnace<EmptyStack, O, T> { | |
| type Next = Furnace<EmptyStack, O, Succ<T>>; | |
| } | |
| impl<N2, I, T: Pos> FurnaceTick for Furnace<Stack<One, I>, Stack<N2, I>, T> { | |
| type Next = Furnace<EmptyStack, Stack<Succ<N2>, I>, Succ<T>>; | |
| } | |
| impl<N, N2, I, T> FurnaceTick for Furnace<Stack<Succ<N>, I>, Stack<N2, I>, T>{ | |
| type Next = Furnace<Stack<N, I>, Stack<Succ<N2>, I>, Succ<T>>; | |
| } | |
| // There are cursed unsound? ways to do type inequality without listing all cases | |
| // Specialization would solve this nicely if it was properly implemented some time | |
| impl<N, N2, T> FurnaceTick for Furnace<Stack<N, IronOre>, Stack<N2, Copper>, T>{ | |
| type Next = Furnace<Stack<N, IronOre>, Stack<N2, Copper>, Succ<T>>; | |
| } | |
| // ... | |
| trait FurnacePassTime<D> { | |
| type After; | |
| fn pass_time(self) -> Self::After; | |
| } | |
| impl<T: FurnaceTick> FurnacePassTime<One> for T { | |
| type After = T::Next; | |
| fn pass_time(self) -> Self::After { | |
| todo!() | |
| } | |
| } | |
| impl<T: FurnaceTick, D> FurnacePassTime<Succ<D>> for T | |
| where T::Next: FurnacePassTime<D> | |
| { | |
| type After = <T::Next as FurnacePassTime<D>>::After; | |
| fn pass_time(self) -> Self::After { | |
| todo!() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment