///|
pub fn[A] Lazy::force(self : Lazy[A]) -> A {
match self.repr {
Value(val) => val
Thunk(fun) => {
let val = fun()
self.repr = Value(val)
val
}
}
}
///|
fn[A] Lazy::from_val(val : A) -> Lazy[A] {
{ repr: Value(val) }
}
///|
fn[A] Lazy::from_fun(fun : () -> A) -> Lazy[A] {
{ repr: Thunk(fun) }
}
///|
pub fn[A] Lazy::new(fun : () -> A) -> Lazy[A] {
Lazy::from_fun(fun)
}
///|
pub fn[A, B] Lazy::map(self : Lazy[A], f : (A) -> B) -> Lazy[B] {
match self.repr {
Value(val) => Lazy::from_val(f(val))
Thunk(fun) =>
Lazy::from_fun(fn() {
let val = fun()
self.repr = Value(val)
f(val)
})
}
}
///|
pub fn[A] Lazy::fix(f : (Lazy[A]) -> Lazy[A]) -> Lazy[A] {
fn fun() -> A {
f(Lazy::from_fun(fun)).force()
}
Lazy::from_fun(fun)
}
///|
pub fn[A] Lazy::join(self : Lazy[Lazy[A]]) -> Lazy[A] {
match self.repr {
Value(val) => val
Thunk(fun) => fun()
}
}
///|
pub fn[A, B] Lazy::bind(self : Lazy[A], f : (A) -> Lazy[B]) -> Lazy[B] {
match self.repr {
Value(val) => f(val)
Thunk(fun) => f(fun())
}
}
///|
pub impl[A : Show] Show for Lazy[A] with output(self, logger) {
self.force().output(logger)
}