gas_monad.mli
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2021 Nomadic Labs <contact@nomadic-labs.com> *)
(* *)
(* Permission is hereby granted, free of charge, to any person obtaining a *)
(* copy of this software and associated documentation files (the "Software"),*)
(* to deal in the Software without restriction, including without limitation *)
(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)
(* and/or sell copies of the Software, and to permit persons to whom the *)
(* Software is furnished to do so, subject to the following conditions: *)
(* *)
(* The above copyright notice and this permission notice shall be included *)
(* in all copies or substantial portions of the Software. *)
(* *)
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)
(* DEALINGS IN THE SOFTWARE. *)
(* *)
(*****************************************************************************)
(** This monad combines:
- a state monad where the state is the context
- two levels of error monad to distinguish gas exhaustion from other errors
It is useful for backtracking on type checking errors without backtracking
the consumed gas.
*)
type ('a, 'trace) t
(** Alias of [('a, 'trace) t] to avoid confusion when the module is open *)
type ('a, 'trace) gas_monad = ('a, 'trace) t
(** [return x] returns a value in the gas-monad. *)
val return : 'a -> ('a, 'trace) t
(** [map f m] maps over successful results of [m] using [f]. *)
val map : ('a -> 'b) -> ('a, 'trace) t -> ('b, 'trace) t
(** [bind m f] binds successful results of [m] and feeds it to [f]. *)
val bind : ('a, 'trace) t -> ('a -> ('b, 'trace) t) -> ('b, 'trace) t
(** [bind_recover m f] binds the result of [m] and feeds it to [f]. It's another
variant of [bind] that allows recovery from inner errors. *)
val bind_recover :
('a, 'trace) t -> (('a, 'trace) result -> ('b, 'trace') t) -> ('b, 'trace') t
(** [of_result r] is a gas-free embedding of the result [r] into the gas monad. *)
val of_result : ('a, 'trace) result -> ('a, 'trace) t
(** [consume_gas c] consumes c amounts of gas. It's a wrapper around
[Gas.consume]. If that fails, the whole computation within the gas-monad
returns an error. See the {!Alpha_context.Gas module} for details.*)
val consume_gas : Alpha_context.Gas.cost -> (unit, 'trace) t
(** [run ctxt m] runs [m] using the given context and returns the result along
with the new context with updated gas. The given context has [unlimited]
mode enabled, through [Gas.set_unlimited], no gas is consumed. *)
val run :
Alpha_context.context ->
('a, 'trace) t ->
(('a, 'trace) result * Alpha_context.context) tzresult
(** [record_trace_level ~error_details f m] returns a new gas-monad value that
when run, records trace levels using [f]. This function has no effect in
the case of a gas-exhaustion error or if [error_details] is [Fast]. *)
val record_trace_eval :
error_details:('error_context, 'error_trace) Script_tc_errors.error_details ->
('error_context -> error) ->
('a, 'error_trace) t ->
('a, 'error_trace) t
(** [fail e] is [return (Error e)] . *)
val fail : 'trace -> ('a, 'trace) t
(** Syntax module for the {!Gas_monad}. This is intended to be opened locally in
functions. Within the scope of this module, the code can include binding
operators, leading to a [let]-style syntax. Similar to {!Lwt_result_syntax}
and other syntax modules. *)
module Syntax : sig
(** [return x] returns a value in the gas-monad. *)
val return : 'a -> ('a, 'trace) t
(** [return_unit] is [return ()] . *)
val return_unit : (unit, 'trace) t
(** [return_none] is [return None] . *)
val return_none : ('a option, 'trace) t
(** [return_some x] is [return (Some x)] . *)
val return_some : 'a -> ('a option, 'trace) t
(** [return_nil] is [return []] . *)
val return_nil : ('a list, 'trace) t
(** [return_true] is [return true] . *)
val return_true : (bool, 'trace) t
(** [return_false] is [return false] . *)
val return_false : (bool, 'trace) t
(** [fail e] is [return (Error e)] . *)
val fail : 'trace -> ('a, 'trace) t
(** [let*] is a binding operator alias for {!bind}. *)
val ( let* ) : ('a, 'trace) t -> ('a -> ('b, 'trace) t) -> ('b, 'trace) t
(** [let+] is a binding operator alias for {!map}. *)
val ( let+ ) : ('a, 'trace) t -> ('a -> 'b) -> ('b, 'trace) t
(** [let*?] is for binding the value from result-only expressions into the
gas-monad. *)
val ( let*? ) :
('a, 'trace) result -> ('a -> ('b, 'trace) t) -> ('b, 'trace) t
end