`val version : string`
`val init : concurrency:int ‑> unit`

To be called to set the amount of concurrency allowed before any call to `exec`.

`module Heart : Tenacious_lib.Heart_intf.S`
`include Core.Monad.S`
`type 'a t`````
`include Base__.Monad_intf.S_without_syntax with type a t := a t`
`type 'a t`````
`include Base__.Monad_intf.Infix with type a t := a t`
`type 'a t`````
`val (>>=) : 'a t ‑> ('a ‑> 'b t) ‑> 'b t`

`t >>= f` returns a computation that sequences the computations represented by two monad elements. The resulting computation first does `t` to yield a value `v`, and then runs the computation returned by `f v`.

`val (>>|) : 'a t ‑> ('a ‑> 'b) ‑> 'b t`

`t >>| f` is `t >>= (fun a -> return (f a))`.

`module Monad_infix : Base__.Monad_intf.Infix with type a t := a t`
`val bind : 'a t ‑> f:('a ‑> 'b t) ‑> 'b t`

`bind t ~f` = `t >>= f`

`val return : 'a ‑> 'a t`

`return v` returns the (trivial) computation that returns v.

`val map : 'a t ‑> f:('a ‑> 'b) ‑> 'b t`

`map t ~f` is t >>| f.

`val join : 'a t t ‑> 'a t`

`join t` is `t >>= (fun t' -> t')`.

`val ignore_m : 'a t ‑> unit t`

`ignore_m t` is `map t ~f:(fun _ -> ())`. `ignore_m` used to be called `ignore`, but we decided that was a bad name, because it shadowed the widely used `Pervasives.ignore`. Some monads still do `let ignore = ignore_m` for historical reasons.

`val all : 'a t list ‑> 'a list t`
`val all_unit : unit t list ‑> unit t`
`val all_ignore : unit t list ‑> unit t`

- Deprecated [since 2018-02] Use [all_unit]

`include Base__.Monad_intf.Syntax with type a t := a t`
`type 'a t`````
`module Let_syntax : sig ... end`
`type 'a tenacious``= 'a t```
`val all_unit : unit t list ‑> unit t`
`val map2 : 'a t ‑> 'b t ‑> f:('a ‑> 'b ‑> 'c) ‑> 'c t`
`val both : 'a t ‑> 'b t ‑> ('a * 'b) t`
`val exec : 'a t ‑> name:Core.String.t Core.Lazy.t ‑> ('a * Heart.t) Async.Deferred.t`

note that `exec` adds a new root in the observable tenacious graph, even if you call it from a function given to `embed` or `lift`.

`val embed : (cancel:Heart.t ‑> ('a * Heart.t) option Async.Deferred.t) ‑> 'a t`
`val memoize : name:Core.String.t Core.Lazy.t ‑> 'a t ‑> 'a t`
`val bracket : 'a t ‑> running:(int ‑> unit) ‑> finished:('a ‑> unit) ‑> cancelled:(unit ‑> unit) ‑> 'a t`

This is most useful in combination with memoize: `memoize (bracket ~running ~finished ~cancelled x)`. Without `memoize`, you can get multiple concurrent `running..canceled` and `running..finished` blocks even when your tenacious doesn't breaks its heart.

`val uncancellable : 'a t ‑> 'a t`
`val desensitize : 'a t ‑> ('a * Heart.t) t`
`val lift : (unit ‑> ('a * Heart.t) Async.Deferred.t) ‑> 'a t`

`lift` is specialization/simplification of `embed`

`val cutoff : equal:('a ‑> 'a ‑> bool) ‑> 'a t ‑> 'a t`

cutoff is dangerous: it will delay heart breakage for the time it takes to re-compute the value so evaluating a `memoize (cutoff x)` might give you stale values even when `memoize x` wouldn't.

We have had a solution in the form of `val protecting_cutoffs : 'a t -> 'a t` that would only return a value after waiting for all cutoffs to finish. We removed the function right after `f322aafe57c1` because it was unused and was preventing an optimization for `Heart.or_broken`.

`val race : 'a t ‑> 'a t ‑> 'a t`

`race` non-deterministically chooses the first computation to succeed, cancels the other.

Note that as it's non-deterministic it should be used with care. Ideally the final result should not depend on which result gets produced first.

`module Stream : sig ... end`

`Stream` provides two things:

`module Result : sig ... end`
`val race_error : ('a, 'e) Result.t ‑> ('b, 'e) Result.t ‑> f:('a ‑> 'b ‑> 'c) ‑> ('c, 'e) Result.t`

non-deterministically choose the faster one to fail. if neither fails, returns both. The `race` caveats apply.

`val race_errors : ('a, 'e) Result.t list ‑> ('a list, 'e) Result.t`
`module Var : sig ... end with type a ten := a t`

A mutable variable whose state can be watched as a Tenacious computation. `'a Var.t` is conceptually a `'a Ref.t` with `Var.{create,get,set,replace}` corresponding to `Ref.{create,(!),(:=),replace}`. The important difference is the `watch` function, that lets you construct tenacious computations that depend on the value of the variable.