// Rose Tree used for shrinking
///|
pub(all) struct Rose[T] {
val : T
branch : Iter[Rose[T]]
} derive(Show)
///|
pub fn[T] new(val : T, branch : Iter[Rose[T]]) -> Rose[T] {
{ val, branch }
}
///|
pub fn[T] join(self : Rose[Rose[T]]) -> Rose[T] {
let tss = self.branch
let ts = self.val.branch
{ val: self.val.val, branch: tss.map(_.join()).concat(ts) }
}
///|
pub fn[T] pure(val : T) -> Rose[T] {
{ val, branch: Iter::empty() }
}
///|
pub fn[T, U] fmap(self : Rose[T], f : (T) -> U) -> Rose[U] {
{ val: f(self.val), branch: self.branch.map(fn(x) { x.fmap(f) }) }
}
///|
pub fn[T, U] bind(self : Rose[T], f : (T) -> Rose[U]) -> Rose[U] {
self.fmap(f).join()
}
///|
pub fn[T] apply(self : Rose[T], f : (T, Iter[Rose[T]]) -> Rose[T]) -> Rose[T] {
f(self.val, self.branch)
}