import { Either } from './Either';
import { Monad } from './Monad';
import { Functor } from '../data/Functor';
/**
* free wraps a value in a free
*/
export declare const free: (a: A) => Return;
/**
* suspend lifts a function into a Free monad to mimic tail call recursion.
*/
export declare const suspend: (f: () => A) => Suspend<(x: {}) => Return<{}>, {}>;
/**
* liftF lifts a Functor into a Free.
*/
export declare const liftF: , A>(f: F) => Suspend>, {}>;
/**
* Free is a Free monad that also implements a Free Applicative (almost).
*
* Inspired by https://cwmyers.github.io/monet.js/#free
*/
export declare abstract class Free implements Monad {
static free: (a: A) => Return;
static suspend: (f: () => A) => Suspend<(x: {}) => Return<{}>, {}>;
static liftF: , A>(f: F) => Suspend>, {}>;
/**
* of
*/
of(a: A): Free;
/**
* map
*/
map(f: (a: A) => B): Free;
/**
* chain
*/
chain(g: (a: A) => Free): Free;
/**
* resume the next stage of the computation
*/
resume(): Either;
/**
* hoist
hoist(func: (fb: Functor) => Functor): Free {
if (this instanceof Suspend) {
return new Suspend((func(this.f))
.map((fr: Free) => fr.hoist(func)))
} else {
return this;
}
}
*/
/**
* cata
*/
cata(f: (f: F) => B, g: (a: A) => B): B;
/**
* go runs the computation to completion using f to extract each stage.
* @summmary go :: Free, A> → (F> → Free) → A
*/
go(f: (next: F) => Free): A;
/**
* run the Free chain to completion
* @summary run :: Free → A
*/
run(): A;
}
export declare class Suspend extends Free {
f: F;
constructor(f: F);
}
export declare class Return extends Free {
a: A;
constructor(a: A);
}