class IO {
// We construct the IO type with a thunk/callback that returns the value when called
constructor( fn ){
this.fn = fn;
}
// IO doesn't do anything until we explicitly call it.
run(){
return this.fn();
}
// Create a new IO value containing a thunk that calls the
// previous one and runs a translation on it
/// map :: IO a -> (a -> b) -> IO b
map(fn){
return new IO(() => fn(
this.run()))
}
// Create a new IO value with a monadic bind. Similar to
map
, but
// the underlying function itself returns an IO that must be unwrapped as well.s
/// bind :: IO a -> (a -> IO b) -> IO b
bind(fn){
return new IO(() => fn(
this.run()).run())
}
}