Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend Monad for folding over lists #133

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base.opam
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ build: [
]
depends: [
"ocaml" {>= "4.10.0"}
"sexplib0"
"sexplib0" {>= "v0.15.0"}
"dune" {>= "2.0.0"}
"dune-configurator"
]
Expand Down
1 change: 1 addition & 0 deletions src/dune
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

(library (name base) (public_name base)
(libraries base_internalhash_types caml sexplib0 shadow_stdlib)
(flags :standard -w -55)
(c_flags :standard -D_LARGEFILE64_SOURCE (:include mpopcnt.sexp))
(c_names exn_stubs int_math_stubs hash_stubs am_testing)
(preprocess no_preprocessing)
Expand Down
2 changes: 2 additions & 0 deletions src/list.ml
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,8 @@ module Cartesian_product = struct
let all_unit = Monad.all_unit
let ignore_m = Monad.ignore_m
let join = Monad.join
let fold_list = Monad.fold_list
let map_list = Monad.map_list

module Monad_infix = struct
let ( >>| ) = ( >>| )
Expand Down
15 changes: 15 additions & 0 deletions src/monad.ml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,21 @@ module Make_general (M : Basic_general) = struct
| [] -> return ()
| t :: ts -> t >>= fun () -> all_unit ts
;;

let fold_list ~f ~init =
let rec loop acc = function
| [] -> return acc
| t :: ts -> f acc t >>= fun acc -> loop acc ts
in
loop init

let map_list ~f =
let rec loop vs = function
| [] -> return (List.rev vs)
| t :: ts -> f t >>= fun v -> loop (v :: vs) ts
in
loop []

end

module Make_indexed (M : Basic_indexed) :
Expand Down
14 changes: 14 additions & 0 deletions src/monad_intf.ml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ module type S_without_syntax = sig
(** Like [all], but ensures that every monadic value in the list produces a unit value,
all of which are discarded rather than being collected into a list. *)
val all_unit : unit t list -> unit t

(** [fold_list ~f ~init [v1; ...; vn]] folds over a list applying a monadic operation,
i.e., performs [f init v1 >>= fun acc -> f acc v2 >>= ... >>= fun acc -> f acc vn]. *)
val fold_list : f:('a -> 'b -> 'a t) -> init:'a -> 'b list -> 'a t

(** [map_list ~f [v1; ...; vn]] applies a monadic operation to each element of a list,
i.e., performs [f v1 >>= fun w1 -> f v2 >>= fun w2 -> ... f vn >>= fun wn -> return [w1; ...; wn]]. *)
val map_list : f:('a -> 'b t) -> 'a list -> 'b list t
end

module type S = sig
Expand Down Expand Up @@ -156,6 +164,8 @@ module type S2 = sig
val ignore_m : (_, 'e) t -> (unit, 'e) t
val all : ('a, 'e) t list -> ('a list, 'e) t
val all_unit : (unit, 'e) t list -> (unit, 'e) t
val fold_list : f:('a -> 'b -> ('a, 'e) t) -> init:'a -> 'b list -> ('a, 'e) t
val map_list : f:('a -> ('b, 'e) t) -> 'a list -> ('b list, 'e) t
end

module type Basic3 = sig
Expand Down Expand Up @@ -218,6 +228,8 @@ module type S3 = sig
val ignore_m : (_, 'd, 'e) t -> (unit, 'd, 'e) t
val all : ('a, 'd, 'e) t list -> ('a list, 'd, 'e) t
val all_unit : (unit, 'd, 'e) t list -> (unit, 'd, 'e) t
val fold_list : f:('a -> 'b -> ('a, 'd, 'e) t) -> init:'a -> 'b list -> ('a, 'd, 'e) t
val map_list : f:('a -> ('b, 'd, 'e) t) -> 'a list -> ('b list, 'd, 'e) t
end

module type Basic_indexed = sig
Expand Down Expand Up @@ -299,6 +311,8 @@ module type S_indexed = sig
val ignore_m : (_, 'i, 'j) t -> (unit, 'i, 'j) t
val all : ('a, 'i, 'i) t list -> ('a list, 'i, 'i) t
val all_unit : (unit, 'i, 'i) t list -> (unit, 'i, 'i) t
val fold_list : f:('a -> 'b -> ('a, 'i, 'i) t) -> init:'a -> 'b list -> ('a, 'i, 'i) t
val map_list : f:('a -> ('b, 'i, 'i) t) -> 'a list -> ('b list, 'i, 'i) t
end

module S_to_S2 (X : S) : S2 with type ('a, 'e) t = 'a X.t = struct
Expand Down