package base

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file comparable_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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
open! Import

module type Infix = Comparisons.Infix
module type Polymorphic_compare = Comparisons.S

module Sign = Sign0 (** @canonical Base.Sign *)

module type With_compare = sig
  (** Various combinators for [compare] and [equal] functions. *)

  (** [lexicographic cmps x y] compares [x] and [y] lexicographically using functions in the
      list [cmps]. *)
  val lexicographic : ('a -> 'a -> int) list -> 'a -> 'a -> int

  (** [lift cmp ~f x y] compares [x] and [y] by comparing [f x] and [f y] via [cmp]. *)
  val lift : ('a -> 'a -> 'result) -> f:('b -> 'a) -> 'b -> 'b -> 'result

  (** [reverse cmp x y = cmp y x]

      Reverses the direction of asymmetric relations by swapping their arguments. Useful,
      e.g., for relations implementing "is a subset of" or "is a descendant of".

      Where reversed relations are already provided, use them directly. For example,
      [Comparable.S] provides [ascending] and [descending], which are more readable as a
      pair than [compare] and [reverse compare]. Similarly, [<=] is more idiomatic than
      [reverse (>=)]. *)
  val reverse : ('a -> 'a -> 'result) -> 'a -> 'a -> 'result

  (** The functions below are analogues of the type-specific functions exported by the
      [Comparable.S] interface. *)

  val equal : ('a -> 'a -> int) -> 'a -> 'a -> bool
  val max : ('a -> 'a -> int) -> 'a -> 'a -> 'a
  val min : ('a -> 'a -> int) -> 'a -> 'a -> 'a
end

module type With_zero = sig
  type t

  val is_positive : t -> bool
  val is_non_negative : t -> bool
  val is_negative : t -> bool
  val is_non_positive : t -> bool

  (** Returns [Neg], [Zero], or [Pos] in a way consistent with the above functions. *)
  val sign : t -> Sign.t
end

module type S = sig
  include Polymorphic_compare


  (** [ascending] is identical to [compare]. [descending x y = ascending y x].  These are
      intended to be mnemonic when used like [List.sort ~compare:ascending] and [List.sort
      ~cmp:descending], since they cause the list to be sorted in ascending or descending
      order, respectively. *)
  val ascending : t -> t -> int

  val descending : t -> t -> int

  (** [between t ~low ~high] means [low <= t <= high] *)
  val between : t -> low:t -> high:t -> bool

  (** [clamp_exn t ~min ~max] returns [t'], the closest value to [t] such that
      [between t' ~low:min ~high:max] is true.

      Raises if [not (min <= max)]. *)
  val clamp_exn : t -> min:t -> max:t -> t

  val clamp : t -> min:t -> max:t -> t Or_error.t

  include Comparator.S with type t := t
end

(** Usage example:

    {[
      module Foo : sig
        type t = ...
        include Comparable.S with type t := t
      end
    ]}

    Then use [Comparable.Make] in the struct (see comparable.mli for an example). *)

module type Comparable = sig
  (** Defines functors for making modules comparable. *)


  (** Usage example:

      {[
        module Foo = struct
          module T = struct
            type t = ... [@@deriving compare, sexp]
          end
          include T
          include Comparable.Make (T)
        end
      ]}

      Then include [Comparable.S] in the signature

      {[
        module Foo : sig
          type t = ...
          include Comparable.S with type t := t
        end
      ]}

      To add an [Infix] submodule:

      {[
        module C = Comparable.Make (T)
        include C
        module Infix = (C : Comparable.Infix with type t := t)
      ]}

      A common pattern is to define a module [O] with a restricted signature. It aims to be
      (locally) opened to bring useful operators into scope without shadowing unexpected
      variable names. E.g., in the [Date] module:

      {[
        module O = struct
          include (C : Comparable.Infix with type t := t)
          let to_string t = ..
        end
      ]}

      Opening [Date] would shadow [now], but opening [Date.O] doesn't:

      {[
        let now = .. in
        let someday = .. in
        Date.O.(now > someday)
      ]} *)

  module type Infix = Infix
  module type S = S
  module type Polymorphic_compare = Polymorphic_compare
  module type With_compare = With_compare
  module type With_zero = With_zero

  include With_compare

  (** Derive [Infix] or [Polymorphic_compare] functions from just [[@@deriving compare]],
      without need for the [sexp_of_t] required by [Make*] (see below). *)

  module Infix (T : sig
      type t [@@deriving_inline compare]

      include Ppx_compare_lib.Comparable.S with type t := t

      [@@@end]
    end) : Infix with type t := T.t

  module Polymorphic_compare (T : sig
      type t [@@deriving_inline compare]

      include Ppx_compare_lib.Comparable.S with type t := t

      [@@@end]
    end) : Polymorphic_compare with type t := T.t

  (** Inherit comparability from a component. *)
  module Inherit (C : sig
      type t [@@deriving_inline compare]

      include Ppx_compare_lib.Comparable.S with type t := t

      [@@@end]
    end) (T : sig
            type t [@@deriving_inline sexp_of]

            val sexp_of_t : t -> Sexplib0.Sexp.t

            [@@@end]

            val component : t -> C.t
          end) : S with type t := T.t

  module Make (T : sig
      type t [@@deriving_inline compare, sexp_of]

      include Ppx_compare_lib.Comparable.S with type t := t

      val sexp_of_t : t -> Sexplib0.Sexp.t

      [@@@end]
    end) : S with type t := T.t

  module Make_using_comparator (T : sig
      type t [@@deriving_inline sexp_of]

      val sexp_of_t : t -> Sexplib0.Sexp.t

      [@@@end]

      include Comparator.S with type t := t
    end) : S with type t := T.t with type comparator_witness := T.comparator_witness

  module Poly (T : sig
      type t [@@deriving_inline sexp_of]

      val sexp_of_t : t -> Sexplib0.Sexp.t

      [@@@end]
    end) : S with type t := T.t

  module With_zero (T : sig
      type t [@@deriving_inline compare, sexp_of]

      include Ppx_compare_lib.Comparable.S with type t := t

      val sexp_of_t : t -> Sexplib0.Sexp.t

      [@@@end]

      val zero : t
    end) : sig
    include With_zero with type t := T.t
  end
end
OCaml

Innovation. Community. Security.