-
Notifications
You must be signed in to change notification settings - Fork 0
/
io.mli
187 lines (113 loc) · 4.51 KB
/
io.mli
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
(* name: io.mli
* synopsis: Interface of rudimentary IO-Monad
* author: Lydia E. van Dijk
* last revision: Thu Nov 13 09:52:54 UTC 2008
* ocaml version: 3.11
*
* Copyright (C) 2006-2008 J. Carette, L. E. van Dijk, O. Kiselyov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*)
(** Rudimentary I/O-monad *)
(** {3 IO-Monad} *)
(** {4 Types} *)
(** Possible errors during an IO-operation. They are named after
their imperative counterparts. *)
type error =
EndOfFile (** Tried to read beyond end of file *)
| IntOfString (** Could not convert [string] to [int] *)
| SysError of string (** Operating system signaled an error.
The [string] takes the precise reason. *)
(** The imperative, "outside" world the {e functional} IO-monad deals with. *)
type world
(** This type takes care of the control-flow similarly to an exception
monad. The ['left] type is for errors, the ['right] type for correct
values. *)
type ('left, 'right) either
(** An IO-monad of type ['a] takes the current world and produces
either a correct value (of type ['a] or an [error] and a new world. *)
type 'a t = world -> (error, 'a) either * world
(** {4 Run-Time Support} *)
(** [__conjure_up ()]
Conjure up a new "world".
This function should only be used once per program. It is best
place in some pre-main initialization code like, for example,
{[
let () =
let world = Io.__conjure_up () in
ignore ((Io.catch (main ()) (fun _error -> ...)) world)
]}
where we call [main] with the initial world. *)
val __conjure_up: unit -> world
(** {4 Fundamental Functions} *)
(** [bind an_iomonad a_function]
Apply [a_function] to [an_iomonad] producing another IO-monad.
[a_function] takes an ['a] value as argument and returns a ['b]
IO-monad. *)
val bind: 'a t -> ('a -> 'b t) -> 'b t
(** [return a_value]
List [a_value] into the IO-monad. *)
val return: 'a -> 'a t
(** [throw an_error]
Throw [an_error] inside the IO-monad. *)
val throw: error -> 'a t
(** [catch an_iomonad a_handler_function]
Catch IO-exceptions from [an_iomonad] and feed them into
[a_handler_function], which takes an [error] value as argument and
returns an ['a] IO-monad. *)
val catch: 'a t -> (error -> 'a t) -> 'a t
(** {4 Output Functions}
All of these functions have exactly the same names as their imperative
counterparts. Moreover, they take the same arguments. *)
(** [print_char a_character] *)
val print_char: char -> unit t
(** [print_string a_string] *)
val print_string: string -> unit t
(** [print_int an_integer] *)
val print_int: int -> unit t
(** [print_float a_float] *)
val print_float: float -> unit t
(** [print_endline a_string] *)
val print_endline: string -> unit t
(** [print_newline ()] *)
val print_newline: unit -> unit t
(** [prerr_char a_character] *)
val prerr_char: char -> unit t
(** [prerr_string a_string] *)
val prerr_string: string -> unit t
(** [prerr_int an_integer] *)
val prerr_int: int -> unit t
(** [prerr_float a_float] *)
val prerr_float: float -> unit t
(** [prerr_endline a_string] *)
val prerr_endline: string -> unit t
(** [prerr_newline ()] *)
val prerr_newline: unit -> unit t
(** {4 Input Functions} *)
(** [read_line ()] *)
val read_line: unit -> string t
(** [read_int ()] *)
val read_int: unit -> int t
(** [read_float ()] *)
val read_float: unit -> float t
(** {4 General Output Functions} *)
(** [open_out a_filename] *)
val open_out: string -> out_channel t
(** [output_char a_channel a_char] *)
val output_char: out_channel -> char -> unit t
(** [output_string a_channel a_string] *)
val output_string: out_channel -> string -> unit t
(** [close_out a_channel] *)
val close_out: out_channel -> unit t