Created
November 6, 2021 01:55
-
-
Save nybble41/fcc3955507cbb5f4f9fe582c1f3329b7 to your computer and use it in GitHub Desktop.
This file contains 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
#![feature(unboxed_closures)] | |
#![feature(fn_traits)] | |
pub mod hlist { | |
mod private { | |
pub trait Sealed {} | |
} | |
pub trait HList: private::Sealed {} | |
pub struct HNil; | |
pub struct HCons<T, R: HList>(pub T, pub R); | |
impl HList for HNil {} | |
impl<T, R: HList> HList for HCons<T, R> {} | |
impl private::Sealed for HNil {} | |
impl<T, R: HList> private::Sealed for HCons<T, R> {} | |
} | |
use hlist::{HList, HCons, HNil}; | |
trait ComposableHList<'i, I: 'i>: HList where Self::Output: 'i { | |
type Output; | |
fn compose(self) -> Box<dyn Fn(I) -> Self::Output + 'i>; | |
} | |
impl<'i, I: 'i> ComposableHList<'i, I> for HNil { | |
type Output = I; | |
fn compose(self) -> Box<dyn Fn(I) -> Self::Output> { | |
Box::new(|i| i) | |
} | |
} | |
impl<'i, I: 'i, O: 'i, R: ComposableHList<'i, I>> ComposableHList<'i, I> for HCons<Box<dyn Fn<(R::Output,), Output = O>>, R> { | |
type Output = O; | |
fn compose(self) -> Box<dyn Fn(I) -> Self::Output + 'i> { | |
let HCons(f, r) = self; | |
let r: Box<dyn Fn(I) -> R::Output> = r.compose(); | |
Box::new(move |i| { f(r(i)) }) | |
} | |
} | |
fn compose<'i, I: 'i, O: 'i, L: ComposableHList<'i, I, Output = O>>(l: L) -> Box<dyn Fn(I) -> O + 'i> { | |
l.compose() | |
} | |
fn test1() | |
{ | |
let atoi: Box<dyn Fn(Box<str>) -> isize> = Box::new(|s| s.parse().unwrap()); | |
let add_one: Box<dyn Fn(isize) -> isize> = Box::new(|i| i + 1); | |
let square: Box<dyn Fn(isize) -> isize> = Box::new(|i| i * i); | |
let unsigned: Box<dyn Fn(isize) -> usize> = Box::new(|i| i as usize); | |
let test: Box<dyn Fn(Box<str>) -> usize> = compose(HCons(unsigned, HCons(square, HCons(add_one, HCons(atoi, HNil))))); | |
println!("{}", test(Box::from("3"))); | |
} | |
fn test2() | |
{ | |
let atoi: Box<dyn Fn(Box<str>) -> isize> = Box::new(|s| s.parse().unwrap()); | |
let unsigned: Box<dyn Fn(isize) -> usize> = Box::new(|i| i as usize); | |
let test: Box<dyn Fn(Box<str>) -> usize> = compose(HCons(unsigned, HCons(atoi, HNil))); | |
println!("{}", test(Box::from("3"))); | |
} | |
fn test3() | |
{ | |
let unsigned: Box<dyn Fn(isize) -> usize> = Box::new(|i| i as usize); | |
let test: Box<dyn Fn(isize) -> usize> = compose(HCons(unsigned, HNil)); | |
println!("{}", test(123)); | |
} | |
fn main() { | |
test1(); | |
test2(); | |
test3(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment