https://gitlab.com/tezos/tezos
Raw File
Tip revision: 044b31726233e62b9822d501571304af3e20733f authored by Gauthier SEBILLE on 20 October 2023, 12:28:38 UTC
RBT: block section for merge profiler
Tip revision: 044b317
state_monad.ml
(*****************************************************************************)
(*                                                                           *)
(* Open Source License                                                       *)
(* Copyright (c) 2023 Nomadic Labs, <contact@nomadic-labs.com>               *)
(* Copyright (c) 2023 Functori, <contact@functori.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.                                                 *)
(*                                                                           *)
(*****************************************************************************)

(** See documentation of the interface below in the mli file. *)

type ('state, 'a) t = 'state -> 'state * 'a

type ('state, 'pass, 'fail) check =
  ('state, [`Pass of 'pass | `Fail of 'fail]) t

module type S = sig
  val bind : ('state, 'a) t -> ('a -> ('state, 'b) t) -> ('state, 'b) t

  val get : ('state -> 'a) -> ('a -> ('state, 'b) t) -> ('state, 'b) t

  val return : 'a -> ('state, 'a) t

  val check :
    ('state, 'pass, 'fail) check ->
    ('pass -> ('state, 'fail) t) ->
    ('state, 'fail) t

  val return_pass : 'pass -> ('state, 'pass, 'fail) check

  val return_fail : 'fail -> ('state, 'pass, 'fail) check

  module Syntax : sig
    val ( let* ) : ('state, 'a) t -> ('a -> ('state, 'b) t) -> ('state, 'b) t

    val ( let*? ) :
      ('state, 'pass, 'fail) check ->
      ('pass -> ('state, 'fail) t) ->
      ('state, 'fail) t

    val ( let*! ) : ('state -> 'a) -> ('a -> ('state, 'b) t) -> ('state, 'b) t

    val return : 'a -> ('state, 'a) t

    val pass : 'pass -> ('state, 'pass, 'fail) check

    val unit : ('state, unit, 'fail) check

    val fail : 'fail -> ('state, 'a, 'fail) check
  end
end

module M : S = struct
  let bind m f state =
    let state, res = m state in
    f res state

  let get p f state =
    let res = p state in
    f res state

  let return x state = (state, x)

  let check c f =
    bind c (function `Pass res -> f res | `Fail output -> return output)

  let return_pass x = `Pass x |> return

  let return_fail x = `Fail x |> return

  module Syntax = struct
    let ( let* ) = bind

    let ( let*? ) = check

    let ( let*! ) = get

    let return = return

    let pass = return_pass

    let unit state = pass () state

    let fail = return_fail
  end
end
back to top