package base

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

Source file applicative.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
open! Import

include Applicative_intf

(** This module serves mostly as a partial check that [S2] and [S] are in sync, but
    actually calling it is occasionally useful. *)
module S_to_S2 (X : S) : (S2 with type ('a, 'e) t = 'a X.t) = struct
  type ('a, 'e) t = 'a X.t
  include (X : S with type 'a t := 'a X.t)
end

module S2_to_S (X : S2) : (S with type 'a t = ('a, unit) X.t) = struct
  type 'a t = ('a, unit) X.t
  include (X : S2 with type ('a, 'e) t := ('a, 'e) X.t)
end

module Args_to_Args2 (X : Args) : (
  Args2 with type ('a, 'e) arg = 'a X.arg
  with type ('f, 'r, 'e) t = ('f, 'r) X.t
) = struct
  type ('a, 'e) arg = 'a X.arg
  type ('f, 'r, 'e) t = ('f, 'r) X.t
  include (X : Args with type 'a arg := 'a X.arg and type ('f, 'r) t := ('f, 'r) X.t)
end
[@@warning "-3"]

module Make2 (X : Basic2) : S2 with type ('a, 'e) t := ('a, 'e) X.t = struct

  include X

  let (<*>) = apply

  let derived_map t ~f = return f <*> t

  let map =
    match X.map with
    | `Define_using_apply -> derived_map
    | `Custom x -> x

  let ( >>|) t f = map t ~f

  let map2 ta tb ~f = map ~f ta <*> tb

  let map3 ta tb tc ~f = map ~f ta <*> tb <*> tc

  let all ts = List.fold_right ts ~init:(return []) ~f:(map2 ~f:(fun x xs -> x :: xs))

  let both ta tb = map2 ta tb ~f:(fun a b -> (a, b))

  let ( *> ) u v = return (fun () y -> y) <*> u <*> v
  let ( <* ) u v = return (fun x () -> x) <*> u <*> v

  let all_unit ts = List.fold ts ~init:(return ()) ~f:( *> )
  let all_ignore = all_unit

  module Applicative_infix = struct
    let ( <*> ) = ( <*> )
    let (  *> ) = (  *> )
    let ( <*  ) = ( <*  )
    let ( >>| ) = ( >>| )
  end
end

module Make (X : Basic) : S with type 'a t := 'a X.t =
  Make2 (struct
    type ('a, 'e) t = 'a X.t
    include (X : Basic with type 'a t := 'a X.t)
  end)

module Make_let_syntax (X : For_let_syntax) (Intf : sig module type S end) (Impl : Intf.S) = struct
  module Let_syntax = struct
    include X
    module Let_syntax = struct
      include X
      module Open_on_rhs = Impl
    end
  end
end

module Make2_using_map2 (X : Basic2_using_map2) =
  Make2 (struct
    include X
    let apply tf tx = map2 tf tx ~f:(fun f x -> f x)
    let map =
      match map with
      | `Custom map        -> `Custom map
      | `Define_using_map2 -> `Define_using_apply
  end)

module Make_using_map2 (X : Basic_using_map2) : S with type 'a t := 'a X.t =
  Make2_using_map2 (struct
    type ('a, 'e) t = 'a X.t
    include (X : Basic_using_map2 with type 'a t := 'a X.t)
  end)

module Make_args' (X : S2) = struct
  open X

  type ('f, 'r, 'e) t_ = { applyN : ('f, 'e) X.t -> ('r, 'e) X.t }

  let nil = { applyN = Fn.id }

  let cons arg t = { applyN = fun d -> t.applyN (apply d arg) }

  let step t ~f = { applyN = fun d -> t.applyN (map ~f d) }

  let (@>) = cons

  let applyN arg t = t.applyN arg

  let mapN ~f t = applyN (return f) t
end

module Make_args (X : S) : Args with type 'a arg := 'a X.t = struct
  include Make_args' (struct
      type ('a, 'e) t = 'a X.t
      include (X : S with type 'a t := 'a X.t)
    end)

  type ('f, 'r) t = ('f, 'r, unit) t_
end
[@@warning "-3"]

module Make_args2 (X : S2) : Args2 with type ('a, 'e) arg := ('a, 'e) X.t = struct
  include Make_args' (X)

  type ('f, 'r, 'e) t = ('f, 'r, 'e) t_
end
[@@warning "-3"]

module Of_monad (M : Monad.S) : S with type 'a t := 'a M.t =
  Make (struct
    type 'a t = 'a M.t
    let return = M.return
    let apply mf mx = M.bind mf ~f:(fun f -> M.map mx ~f)
    let map = `Custom M.map
  end)

module Compose (F : S) (G : S) : S with type 'a t = 'a F.t G.t = struct
  type 'a t = 'a F.t G.t
  include Make (struct
      type nonrec 'a t = 'a t
      let return a = G.return (F.return a)
      let apply tf tx = G.apply (G.map ~f:F.apply tf) tx
      let custom_map t ~f = G.map ~f:(F.map ~f) t
      let map = `Custom custom_map
    end)
end

module Pair (F : S) (G : S) : S with type 'a t = 'a F.t * 'a G.t = struct
  type 'a t = 'a F.t * 'a G.t
  include Make (struct
      type nonrec 'a t = 'a t
      let return a = (F.return a, G.return a)
      let apply tf tx = (F.apply (fst tf) (fst tx), G.apply (snd tf) (snd tx))
      let custom_map t ~f = (F.map ~f (fst t), G.map ~f (snd t))
      let map = `Custom custom_map
    end)
end
OCaml

Innovation. Community. Security.