Skip to content

Instantly share code, notes, and snippets.

@Pzixel
Last active June 21, 2020 21:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pzixel/3fc17be254f6c6bcaf88711e12bddd2c to your computer and use it in GitHub Desktop.
Save Pzixel/3fc17be254f6c6bcaf88711e12bddd2c to your computer and use it in GitHub Desktop.
pub struct IO<T>(Box<dyn FnOnce() -> T>);
impl<T: 'static> IO<T> {
pub unsafe fn perform_io(self) -> T {
self.0()
}
pub fn new(f: impl FnOnce() -> T + 'static) -> Self {
Self(Box::new(f))
}
pub fn map<TResult>(self, f: impl FnOnce(T) -> TResult + 'static) -> IO<TResult> {
IO(Box::new(move || f(unsafe { self.perform_io() })))
}
pub fn pure(x: T) -> IO<T> {
IO(Box::new(move || x))
}
pub fn flat_map<TResult: 'static>(self, f : impl FnOnce(T) -> IO<TResult> + 'static) -> IO<TResult> {
IO(Box::new(move || unsafe {
let value = self.perform_io();
f(value).perform_io()
}))
}
}
fn get_line() -> IO<String> {
IO::new(|| {
let mut s = String::new();
std::io::stdin().read_line(&mut s).expect("Did not enter a correct string");
s
})
}
fn write_line(s: String) -> IO<()> {
IO::new(move || {
println!("{}", s);
})
}
fn haskell_main() -> IO<()> {
get_line().flat_map(|x| write_line(x))
}
fn haskell_runtime() {
unsafe {
haskell_main().perform_io();
}
}
fn main() {
haskell_runtime();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment