Skip to content

Commit

Permalink
refactor: redo signatures and fix documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
favonia committed Oct 31, 2023
1 parent 80dca8d commit 273453a
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 63 deletions.
9 changes: 4 additions & 5 deletions src/Reader.ml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module type S =
sig
module Env : Sigs.Type

val read : unit -> Env.t
val scope : (Env.t -> Env.t) -> (unit -> 'a) -> 'a
val run : env:Env.t -> (unit -> 'a) -> 'a
type env
val read : unit -> env
val scope : (env -> env) -> (unit -> 'a) -> 'a
val run : env:env -> (unit -> 'a) -> 'a
val register_printer : ([`Read] -> string option) -> unit
end

Expand Down
17 changes: 7 additions & 10 deletions src/Reader.mli
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,21 @@
]}
*)

(** This should be equivalent to {!Unmonad} applying to the standard reader monad. *)

module type S =
sig
(** Signatures of read effects. *)

(** Type of environments. *)
module Env : Sigs.Type
(** @open *)
type env
(** The type of environments. *)

val read : unit -> Env.t
val read : unit -> env
(** Read the environment. *)

val scope : (Env.t -> Env.t) -> (unit -> 'a) -> 'a
val scope : (env -> env) -> (unit -> 'a) -> 'a
(** [scope f t] runs the thunk [t] under the new environment that is the result of applying [f] to the current environment. *)

val run : env:Env.t -> (unit -> 'a) -> 'a
(** [run t] runs the thunk [t] which may perform reading effects. *)
val run : env:env -> (unit -> 'a) -> 'a
(** [run ~env t] runs the thunk [t] which may perform reading effects on the value [env]. *)

val register_printer : ([`Read] -> string option) -> unit
(** [register_printer p] registers a printer [p] via {!val:Printexc.register_printer} to convert the unhandled internal effect into a string for the OCaml runtime system to display. Ideally, the internal effect should have been handled by {!val:run} and there is no need to use this function, but when it is not the case, this function can be helpful for debugging. The functor {!module:Reader.Make} always registers a simple printer to suggest using {!val:run}, but you can register new ones to override it. The return type of the printer [p] should return [Some s] where [s] is the resulting string, or [None] if it chooses not to convert a particular effect. The registered printers are tried in reverse order until one of them returns [Some s] for some [s]; that is, the last registered printer is tried first. Note that this function is a wrapper of {!val:Printexc.register_printer} and all the registered printers (via this function or {!val:Printexc.register_printer}) are put into the same list.
Expand All @@ -44,5 +41,5 @@ sig
*)
end

module Make (Env : Sigs.Type) : S with module Env := Env
module Make (Env : Sigs.Type) : S with type env := Env.t
(** The implementation of read effects. *)
9 changes: 4 additions & 5 deletions src/Sequencer.ml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module type S =
sig
module Elt : Sigs.Type

val yield : Elt.t -> unit
val run : (unit -> unit) -> Elt.t Seq.t
val register_printer : ([`Yield of Elt.t] -> string option) -> unit
type elt
val yield : elt -> unit
val run : (unit -> unit) -> elt Seq.t
val register_printer : ([`Yield of elt] -> string option) -> unit
end

module Make (Elt : Sigs.Type) =
Expand Down
12 changes: 6 additions & 6 deletions src/Sequencer.mli
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ module type S =
sig
(** Signatures of sequencing effects. *)

module Elt : Sigs.Type
(** @open *)
type elt
(** The type of elements. *)

val yield : Elt.t -> unit
val yield : elt -> unit
(** Yield the element. *)

val run : (unit -> unit) -> Elt.t Seq.t
val run : (unit -> unit) -> elt Seq.t
(** [run t] runs the thunk [t] which may perform sequencing effects. *)

val register_printer : ([`Yield of Elt.t] -> string option) -> unit
val register_printer : ([`Yield of elt] -> string option) -> unit
(** [register_printer p] registers a printer [p] via {!val:Printexc.register_printer} to convert unhandled internal effects into strings for the OCaml runtime system to display. Ideally, all internal effects should have been handled by {!val:run} and there is no need to use this function, but when it is not the case, this function can be helpful for debugging. The functor {!module:Sequencer.Make} always registers a simple printer to suggest using {!val:run}, but you can register new ones to override it. The return type of the printer [p] should return [Some s] where [s] is the resulting string, or [None] if it chooses not to convert a particular effect. The registered printers are tried in reverse order until one of them returns [Some s] for some [s]; that is, the last registered printer is tried first. Note that this function is a wrapper of {!val:Printexc.register_printer} and all the registered printers (via this function or {!val:Printexc.register_printer}) are put into the same list.
The input type of the printer [p] is a variant representation of the internal effects used in this module. They correspond to the effects trigger by {!val:yield}. More precisely, [`Yield elt] corresponds to the effect triggered by [yield elt].
Expand All @@ -37,5 +37,5 @@ sig
*)
end

module Make (Elt : Sigs.Type) : S with module Elt := Elt
module Make (Elt : Sigs.Type) : S with type elt := Elt.t
(** The implementation of sequencing effects. *)
13 changes: 6 additions & 7 deletions src/State.ml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
module type S =
sig
module State : Sigs.Type

val get : unit -> State.t
val set : State.t -> unit
val modify : (State.t -> State.t) -> unit
val run : init:State.t -> (unit -> 'a) -> 'a
val register_printer : ([`Get | `Set of State.t] -> string option) -> unit
type state
val get : unit -> state
val set : state -> unit
val modify : (state -> state) -> unit
val run : init:state -> (unit -> 'a) -> 'a
val register_printer : ([`Get | `Set of state] -> string option) -> unit
end

module Make (State : Sigs.Type) =
Expand Down
23 changes: 10 additions & 13 deletions src/State.mli
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,27 @@
]}
*)

(** This should be equivalent to {!module:Unmonad} applying to the standard state monad when continuations are one-shot.
(The current implementation uses mutable references and this statement has not been formally proved.) *)

module type S =
sig
(** Signatures of read effects. *)

module State : Sigs.Type
(** @open *)
type state
(** The type of states. *)

val get : unit -> State.t
val get : unit -> state
(** [get ()] reads the current state. *)

val set : State.t -> unit
val set : state -> unit
(** [set x] makes [x] the new state. *)

val modify : (State.t -> State.t) -> unit
val modify : (state -> state) -> unit
(** [modify f] applies [f] to the current state and then set the result as the new state. *)

val run : init:State.t -> (unit -> 'a) -> 'a
(** [run t] runs the thunk [t] which may perform state effects. *)
val run : init:state -> (unit -> 'a) -> 'a
(** [run ~init t] runs the thunk [t] which may perform state effects. The initial state is [init]. *)

val register_printer : ([`Get | `Set of State.t] -> string option) -> unit
(** [register_printer p] registers a printer [p] via {!val:Printexc.register_printer} to convert unhandled internal effects into strings for the OCaml runtime system to display. Ideally, all internal effects should have been handled by {!val:run} and there is no need to use this function, but when it is not the case, this function can be helpful for debugging. The functor {!module:State.Make} always registers a simple printer to suggest using {!val:run}, but you can register new ones to override it. The return type of the printer [p] should return [Some s] where [s] is the resulting string, or [None] if it chooses not to convert a particular effect. The registered printers are tried in reverse order until one of them returns [Some s] for some [s]; that is, the last registered printer is tried first. Note that this function is a wrapper of {!val:Printexc.register_printer} and all the registered printers (via this function or {!val:Printexc.register_printer}) are put into the same list.
val register_printer : ([`Get | `Set of state] -> string option) -> unit
(** [register_printer p] registers a printer [p] via {!val:Printexc.register_printer} to convert unhandled internal effects into strings for the OCaml runtime system to display. Ideally, all internal effects should have been handled by {!val:run} and there is no need to use this function, but when it is not the case, this function can be helpful for debugging. The functor {!module:Make} always registers a simple printer to suggest using {!val:run}, but you can register new ones to override it. The return type of the printer [p] should return [Some s] where [s] is the resulting string, or [None] if it chooses not to convert a particular effect. The registered printers are tried in reverse order until one of them returns [Some s] for some [s]; that is, the last registered printer is tried first. Note that this function is a wrapper of {!val:Printexc.register_printer} and all the registered printers (via this function or {!val:Printexc.register_printer}) are put into the same list.
The input type of the printer [p] is a variant representation of the internal effects used in this module. They correspond to the effects trigger by {!val:get} and {!val:set}. More precisely,
- [`Get] corresponds to the effect triggered by [get ()].
Expand All @@ -44,5 +41,5 @@ sig
*)
end

module Make (State : Sigs.Type) : S with module State := State
module Make (State : Sigs.Type) : S with type state := State.t
(** The implementation of state effects. *)
12 changes: 6 additions & 6 deletions src/UniqueID.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module type S =
sig
module Elt : Sigs.Type
type elt

module ID :
sig
Expand All @@ -12,11 +12,11 @@ sig
end
type id = ID.t

val register : Elt.t -> id
val retrieve : id -> Elt.t
val export : unit -> Elt.t Seq.t
val run : ?init:Elt.t Seq.t -> (unit -> 'a) -> 'a
val register_printer : ([`Register of Elt.t | `Retrieve of id | `Export] -> string option) -> unit
val register : elt -> id
val retrieve : id -> elt
val export : unit -> elt Seq.t
val run : ?init:elt Seq.t -> (unit -> 'a) -> 'a
val register_printer : ([`Register of elt | `Retrieve of id | `Export] -> string option) -> unit
end

module Make (Elt : Sigs.Type) =
Expand Down
16 changes: 8 additions & 8 deletions src/UniqueID.mli
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ module type S =
sig
(** Signatures of the effects. *)

module Elt : Sigs.Type
(** @open *)
type elt
(** The type of elements *)

(** The type of IDs and its friends. *)
module ID :
Expand All @@ -32,22 +32,22 @@ sig
type id = ID.t
(** The type of unique IDs. The client should not assume a particular indexing scheme. *)

val register : Elt.t -> id
val register : elt -> id
(** Register a new item and get an ID. Note that registering the same item twice will get two different IDs. *)

val retrieve : id -> Elt.t
val retrieve : id -> elt
(** Retrieve the item associated with the ID. *)

val export : unit -> Elt.t Seq.t
val export : unit -> elt Seq.t
(** Export the internal storage for serialization. Once exported, the representation is persistent and can be traversed without the effect handler. *)

val run : ?init:Elt.t Seq.t -> (unit -> 'a) -> 'a
val run : ?init:elt Seq.t -> (unit -> 'a) -> 'a
(** [run t] runs the thunk [t] and handles the effects for generating unique IDs.
@param init The initial storage, which should be the output of some previous {!val:export}.
*)

val register_printer : ([`Register of Elt.t | `Retrieve of id | `Export] -> string option) -> unit
val register_printer : ([`Register of elt | `Retrieve of id | `Export] -> string option) -> unit
(** [register_printer p] registers a printer [p] via {!val:Printexc.register_printer} to convert unhandled internal effects into strings for the OCaml runtime system to display. Ideally, all internal effects should have been handled by {!val:run} and there is no need to use this function, but when it is not the case, this function can be helpful for debugging. The functor {!module:UniqueID.Make} always registers a simple printer to suggest using {!val:run}, but you can register new ones to override it. The return type of the printer [p] should return [Some s] where [s] is the resulting string, or [None] if it chooses not to convert a particular effect. The registered printers are tried in reverse order until one of them returns [Some s] for some [s]; that is, the last registered printer is tried first. Note that this function is a wrapper of {!val:Printexc.register_printer} and all the registered printers (via this function or {!val:Printexc.register_printer}) are put into the same list.
The input type of the printer [p] is a variant representation of the internal effects used in this module. They correspond to the effects trigger by {!val:register}, {!val:retrieve} and {!val:export}. More precisely,
Expand All @@ -59,5 +59,5 @@ sig
*)
end

module Make (Elt : Sigs.Type) : S with module Elt := Elt
module Make (Elt : Sigs.Type) : S with type elt := Elt.t
(** The implementation of the effects. *)
2 changes: 1 addition & 1 deletion test/TestReader.ml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ let gen_cmd =

let gen_prog = Q.Gen.list gen_cmd

module ReaderTester (S : Algaeff.Reader.S with module Env := Int) =
module ReaderTester (S : Algaeff.Reader.S with type env := int) =
struct
let trace ~env prog =
let rec go =
Expand Down
2 changes: 1 addition & 1 deletion test/TestSequencer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ and prog = cmd list
let gen_cmd = Q.Gen.map (fun i -> Yield i) Q.Gen.int
let gen_prog = Q.Gen.list gen_cmd

module SequencerTester (S : Algaeff.Sequencer.S with module Elt := Int) =
module SequencerTester (S : Algaeff.Sequencer.S with type elt := int) =
struct
let trace (prog : prog) =
let go = function (Yield i) -> S.yield i in
Expand Down
2 changes: 1 addition & 1 deletion test/TestState.ml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ let gen_cmd =

let gen_prog = Q.Gen.list gen_cmd

module StateTester (S : Algaeff.State.S with module State := Int) =
module StateTester (S : Algaeff.State.S with type state := int) =
struct
let trace ~init prog =
let go =
Expand Down

0 comments on commit 273453a

Please sign in to comment.