Input-Output
Input-output functions do calculate a value (often of type
unit) but during their calculation they cause a modification
of the state of the input-output peripherals: modification of the
state of the keyboard buffer, outputting to the screen,
writing in a file, or modification of a read pointer. The following two
types are predefined: in_channel and out_channel
for, respectively, input channels and output channels. When an end of
file is met, the exception End_of_file is raised. Finally,
the following three constants correspond to the standard channels for
input, output, and error in Unix fashion: stdin,
stdout, and stderr.
Channels
The input-output functions from the Objective CAML standard library
manipulate communication channels: values of type
in_channel or out_channel. Apart from the three
standard predefined values, the creation of a channel uses one of the
following functions:
# open_in;;
- : string -> in_channel = <fun>
# open_out;;
- : string -> out_channel = <fun>
open_in opens the file if it exists2, and otherwise raises the exception
Sys_error.
open_out creates the specified file if it does not exist or
truncates it if it does.
# let
ic
=
open_in
"koala"
;;
val ic : in_channel = <abstr>
# let
oc
=
open_out
"koala"
;;
val oc : out_channel = <abstr>
The functions for closing channels are:
# close_in
;;
- : in_channel -> unit = <fun>
# close_out
;;
- : out_channel -> unit = <fun>
Reading and Writing
The most general functions for reading and writing are the following:
# input_line
;;
- : in_channel -> string = <fun>
# input
;;
- : in_channel -> string -> int -> int -> int = <fun>
# output
;;
- : out_channel -> string -> int -> int -> unit = <fun>
-
input_line
ic: reads from input channel ic
all the characters up to the first carriage return or end of file, and
returns them in the form of a list of characters (excluding the
carriage return).
- input
ic
s
p
l: attempts to read l
characters from an input channel ic and stores them in the
list s starting from the pth
character. The number of characters actually read is returned.
- output
oc
s
p
l: writes on an output channel
oc part of the list s, starting at the p-th
character, with length l.
The following functions read from standard input or write to standard
output:
# read_line
;;
- : unit -> string = <fun>
# print_string
;;
- : string -> unit = <fun>
# print_newline
;;
- : unit -> unit = <fun>
Other values of simple types can also be read directly or
appended. These are the values of types which can be converted into
lists of characters.
Local declarations and order of evaluation
We can simulate a sequence of printouts with expressions
of the form let x = e1 in e2. Knowing that, in general,
x is a local variable which can be used in e2, we
know that e1 is evaluated first and then comes the turn of
e2. If the two expressions are imperative functions
whose results are () but which have side effects, then we
have executed them in the right order. In particular, since we know
the return value of e1---the constant () of
type unit---we get a sequence of printouts by writing the
sequence of nested declarations which pattern match on ().
# let
()
=
print_string
"and one,"
in
let
()
=
print_string
" and two,"
in
let
()
=
print_string
" and three"
in
print_string
" zero"
;;
and one, and two, and three zero- : unit = ()
Example: Higher/Lower
The following example concerns the game ``Higher/Lower''
which consists of choosing a number which the user must
guess at. The program indicates at each turn whether the chosen number is
smaller or bigger than the proposed number.
#
let
rec
hilo
n
=
let
()
=
print_string
"type a number: "
in
let
i
=
read_int
()
in
if
i
=
n
then
let
()
=
print_string
"BRAVO"
in
let
()
=
print_newline
()
in
print_newline
()
else
let
()
=
if
i
<
n
then
let
()
=
print_string
"Higher"
in
print_newline
()
else
let
()
=
print_string
"Lower"
in
print_newline
()
in
hilo
n
;;
val hilo : int -> unit = <fun>
Here is an example session:
# hilo 64;;
type a number: 88
Lower
type a number: 44
Higher
type a number: 64
BRAVO
- : unit = ()