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
open Preface_core.Fun
open Preface_core.Fun.Infix
module Core_via_map_and_duplicate
(Req : Preface_specs.Comonad.WITH_MAP_AND_DUPLICATE) :
Preface_specs.Comonad.CORE with type 'a t = 'a Req.t = struct
include Req
let extend f = duplicate %> map f
let compose_left_to_right f g = duplicate %> map f %> g
end
module Core_via_extend (Req : Preface_specs.Comonad.WITH_EXTEND) :
Preface_specs.Comonad.CORE with type 'a t = 'a Req.t = struct
include Req
let duplicate a = extend id a
let compose_left_to_right f g = extend f %> g
let map f = extend @@ (extract %> f)
end
module Core_via_cokleisli_composition
(Req : Preface_specs.Comonad.WITH_COKLEISLI_COMPOSITION) :
Preface_specs.Comonad.CORE with type 'a t = 'a Req.t = struct
include Req
let extend f = compose_left_to_right f id
let duplicate a = compose_left_to_right id id a
let map f = compose_left_to_right (extract %> f) id
end
module Syntax (Core : Preface_specs.Comonad.CORE) :
Preface_specs.Comonad.SYNTAX with type 'a t = 'a Core.t = struct
type 'a t = 'a Core.t
let ( let@ ) e f = Core.extend f e
let ( let+ ) e f = Core.map f e
end
module Operation (Core : Preface_specs.Comonad.CORE) :
Preface_specs.Comonad.OPERATION with type 'a t = 'a Core.t = struct
include Functor.Operation (Core)
let lift = Core.map
let lift2 f a = Core.(map @@ extract @@ lift f a)
let lift3 f a b = Core.(map @@ extract @@ lift2 f a b)
let compose_right_to_left f g = Core.compose_left_to_right g f
end
module Infix
(Core : Preface_specs.Comonad.CORE)
(Operation : Preface_specs.Comonad.OPERATION with type 'a t = 'a Core.t) :
Preface_specs.Comonad.INFIX with type 'a t = 'a Core.t = struct
include Functor.Infix (Core) (Operation)
let ( <<= ) = Core.extend
let ( =>> ) a f = Core.extend f a
let ( =>= ) = Core.compose_left_to_right
let ( =<= ) = Operation.compose_right_to_left
let ( <@> ) f a = Core.(map (extract f) a)
let ( <@@> ) a f = f <@> a
let ( <@ ) a = Core.(map @@ extract @@ map const a)
let ( @> ) a b = b <@ a
end
module Via
(Core : Preface_specs.Comonad.CORE)
(Operation : Preface_specs.Comonad.OPERATION with type 'a t = 'a Core.t)
(Syntax : Preface_specs.Comonad.SYNTAX with type 'a t = 'a Core.t)
(Infix : Preface_specs.Comonad.INFIX with type 'a t = 'a Core.t) :
Preface_specs.COMONAD with type 'a t = 'a Core.t = struct
include Core
include Operation
include Syntax
module Syntax = Syntax
include Infix
module Infix = Infix
end
module Via_map_and_duplicate
(Req : Preface_specs.Comonad.WITH_MAP_AND_DUPLICATE) :
Preface_specs.COMONAD with type 'a t = 'a Req.t = struct
module Core = Core_via_map_and_duplicate (Req)
module Operation = Operation (Core)
module Syntax = Syntax (Core)
module Infix = Infix (Core) (Operation)
include Core
include Operation
include Syntax
include Infix
end
module Via_extend (Req : Preface_specs.Comonad.WITH_EXTEND) :
Preface_specs.COMONAD with type 'a t = 'a Req.t = struct
module Core = Core_via_extend (Req)
module Operation = Operation (Core)
module Syntax = Syntax (Core)
module Infix = Infix (Core) (Operation)
include Core
include Operation
include Syntax
include Infix
end
module Via_cokleisli_composition
(Req : Preface_specs.Comonad.WITH_COKLEISLI_COMPOSITION) :
Preface_specs.COMONAD with type 'a t = 'a Req.t = struct
module Core = Core_via_cokleisli_composition (Req)
module Operation = Operation (Core)
module Syntax = Syntax (Core)
module Infix = Infix (Core) (Operation)
include Core
include Operation
include Syntax
include Infix
end