Source file monad_intf.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
(** Minimum monad signature with an additional type parameter ['z]  *)
module type S2 = sig
  type (+'a, 'z) t
  val return : 'a -> ('a, 'z) t
  val bind : ('a, 'z) t -> ('a -> ('b, 'z) t) -> ('b, 'z) t
end

(** Infix name space for [S2] *)
module type Infix2 = sig
  type (+'a, 'z) t

  val ( >>= ) : ('a, 'z) t -> ('a -> ('b, 'z) t) -> ('b, 'z) t
  (** synonym of [bind] *)
    
  val ( >>| ) : ('a, 'z) t -> ('a -> 'b) -> ('b, 'z) t
  (** synonum of [fmap], with the flipped arguments *)

  (** Applicative style binops *)
    
  val (^<$>) : ('a -> 'b) -> ('a, 'z) t -> ('b, 'z) t
    (** same as map, <$> in Haskell *)
    
  val (/<*>) : ('a -> 'b, 'z) t -> ('a, 'z) t -> ('b, 'z) t
  (** <*> in Haskell *)
end

(** Extension of [S2] *)
module type EX2 = sig
  type ('a, 'z) t

  val fmap : ('a -> 'b) -> ('a, 'z) t -> ('b, 'z) t
  (** fmap in Haskell *)

  val liftM : ('a -> 'b) -> ('a, 'z) t -> ('b, 'z) t
  (** Synonym of [fmap] *)

  val fmap2 : ('a -> 'b -> 'c) -> ('a, 'z) t -> ('b, 'z) t -> ('c, 'z) t
  (** fmap2 in Haskell *)

  val liftM2 : ('a -> 'b -> 'c) -> ('a, 'z) t -> ('b, 'z) t -> ('c, 'z) t
  (** synonym of [fmap2] in Haskell *)

  val void : ('a, 'z) t -> (unit, 'z) t

  val seq : ('a, 'z) t list -> ('a list, 'z) t
  (** sequence in Haskell. Not tail recursive. *)

  val seq_ : (unit, 'z) t list -> (unit, 'z) t
  (** sequence_ in Haskell. Not tail recursive. *)

  val mapM : ('a -> ('b, 'z) t) -> 'a list -> ('b list, 'z) t
  (** Not tail recursive *)

  val mapM_ : ('a -> (unit, 'z) t) -> 'a list -> (unit, 'z) t
  (** Not tail recursive *)

  val iteri : (int -> 'a -> (unit, 'z) t) -> 'a list -> (unit, 'z) t
  (** Iteration with index starting from [0]. Not tail recursive. *)

  val for_ : int -> int -> (int -> (unit, 'z) t) -> (unit, 'z) t
  (** for like iteration. Not tail recursive *)

  val join : (('a, 'z) t, 'z) t -> ('a, 'z) t
end

(** The final unified Monad API for [S2] *)
module type T2 = sig
  include S2
  include EX2 with type ('a, 'z) t := ('a, 'z) t
  include Infix2 with type ('a, 'z) t := ('a, 'z) t

  module S : S2 with type ('a, 'z) t := ('a, 'z) t
  module EX : EX2 with type ('a, 'z) t := ('a, 'z) t
  module Infix : Infix2 with type ('a, 'z) t := ('a, 'z) t
end

module type S1 = sig
  type +'a t
  val return : 'a -> 'a t
  val bind : 'a t -> ('a -> 'b t) -> 'b t
end

(** Infix name space for [S1] *)
module type Infix1 = sig
  type +'a t

  val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t
  (** synonym of [bind] *)
    
  val ( >>| ) : 'a t -> ('a -> 'b) -> 'b t
  (** synonum of [fmap], with the flipped arguments *)

  (** Applicative style binops *)
    
  val (^<$>) : ('a -> 'b) -> 'a t -> 'b t
    (** same as map, <$> in Haskell *)
    
  val (/<*>) : ('a -> 'b) t -> 'a t -> 'b t
  (** <*> in Haskell *)
end

(** Extension of [S1] *)
module type EX1 = sig
  type 'a t

  val fmap : ('a -> 'b) -> 'a t -> 'b t
  (** fmap in Haskell *)

  val liftM : ('a -> 'b) -> 'a t -> 'b t
  (** synonym of [fmap] *)

  val fmap2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
  (** fmap2 in Haskell *)

  val liftM2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
  (** synonym of [fmap2] *)

  val void : 'a t -> unit t

  val seq : 'a t list -> 'a list t
  (** sequence in Haskell. Not tail recursive. *)

  val seq_ : unit t list -> unit t
  (** sequence_ in Haskell. Not tail recursive. *)

  val mapM : ('a -> 'b t) -> 'a list -> 'b list t
  (** Not tail recursive *)

  val mapM_ : ('a -> unit t) -> 'a list -> unit t
  (** Not tail recursive *)

  val iteri : (int -> 'a -> unit t) -> 'a list -> unit t
  (** Iteration with index starting from [0]. Not tail recursive. *)

  val for_ : int -> int -> (int -> unit t) -> unit t
  (** for like iteration. Not tail recursive *)

  val join : 'a t t -> 'a t
 end

(** The final unified Monad API for [S1] *)
module type T1 = sig
  include S1
  include EX1 with type 'a t := 'a t
  include Infix1 with type 'a t := 'a t

  module S : S1 with type 'a t := 'a t
  module EX : EX1 with type 'a t := 'a t
  module Infix : Infix1 with type 'a t := 'a t
end

module type S = S1
module type T = T1
module type EX = EX1
module type Infix = Infix1