[m-rev.] for review: io__foldl
Simon Taylor
stayl at cs.mu.OZ.AU
Tue Jan 15 19:46:12 AEDT 2002
Estimated hours taken: 1
NEWS:
library/io.m:
Add `io__input_stream_foldl', `io__input_stream_foldl_io'
and `io__input_stream_foldl2_io', which apply a predicate
to each character of an input stream in turn.
Add a new result type `io__maybe_partial_res' which is
used for operations which can return a partial result
like io__input_stream_foldl* and io__read_file.
tests/general/Mmakefile:
tests/general/io_foldl.{m,exp}:
Test case.
Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.237
diff -u -u -r1.237 NEWS
--- NEWS 15 Jan 2002 07:19:04 -0000 1.237
+++ NEWS 15 Jan 2002 07:34:17 -0000
@@ -65,6 +65,14 @@
Changes to the Mercury standard library:
+* `io__read_file' and `io__read_file_as_string' now have better error
+ handling. The result types have changed, so code using these predicates
+ will need minor modifications.
+
+* We've added predicates `io__input_stream_foldl', `io__input_stream_foldl_io'
+ and `io__input_stream_foldl2_io', which apply a predicate to each character
+ of an input stream in turn.
+
* We've added four functions to list.m for mapping functions over
corresponding members of lists: list__map_corresponding/3,
list__map_corresponding3/4, list__filter_map_corresponding/3
Index: library/io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.237
diff -u -u -r1.237 io.m
--- library/io.m 14 Dec 2001 16:05:40 -0000 1.237
+++ library/io.m 15 Jan 2002 08:09:09 -0000
@@ -69,6 +69,12 @@
:- type io__res(T) ---> ok(T)
; error(io__error).
+ % io__maybe_partial_res is used where it is possible to return
+ % a partial result when an error occurs,
+:- type io__maybe_partial_res(T)
+ ---> ok(T)
+ ; error(T, io__error).
+
:- type io__result ---> ok
; eof
; error(io__error).
@@ -128,17 +134,45 @@
% Reads a line from the current input stream, returns the
% result as a string.
-:- pred io__read_file(io__result(list(char)), io__state, io__state).
+:- pred io__read_file(io__maybe_partial_res(list(char)), io__state, io__state).
:- mode io__read_file(out, di, uo) is det.
% Reads all the characters from the current input stream until
% eof or error.
-:- pred io__read_file_as_string(io__res, string, io__state, io__state).
-:- mode io__read_file_as_string(out, out, di, uo) is det.
+:- pred io__read_file_as_string(io__maybe_partial_res(string),
+ io__state, io__state).
+:- mode io__read_file_as_string(out, di, uo) is det.
% Reads all the characters from the current input stream until
% eof or error. Returns the result as a string rather than
% as a list of char.
+:- pred io__input_stream_foldl(pred(char, T, T),
+ T, io__maybe_partial_res(T), io__state, io__state).
+:- mode io__input_stream_foldl((pred(in, in, out) is det),
+ in, out, di, uo) is det.
+:- mode io__input_stream_foldl((pred(in, in, out) is cc_multi),
+ in, out, di, uo) is cc_multi.
+% Applies the given closure to each character read from
+% the input stream in turn, until eof or error.
+
+:- pred io__input_stream_foldl_io(pred(char, io__state, io__state),
+ io__res, io__state, io__state).
+:- mode io__input_stream_foldl_io((pred(in, di, uo) is det),
+ out, di, uo) is det.
+:- mode io__input_stream_foldl_io((pred(in, di, uo) is cc_multi),
+ out, di, uo) is cc_multi.
+% Applies the given closure to each character read from
+% the input stream in turn, until eof or error.
+
+:- pred io__input_stream_foldl2_io(pred(char, T, T, io__state, io__state),
+ T, io__maybe_partial_res(T), io__state, io__state).
+:- mode io__input_stream_foldl2_io((pred(in, in, out, di, uo) is det),
+ in, out, di, uo) is det.
+:- mode io__input_stream_foldl2_io((pred(in, in, out, di, uo) is cc_multi),
+ in, out, di, uo) is cc_multi.
+% Applies the given closure to each character read from
+% the input stream in turn, until eof or error.
+
:- pred io__putback_char(char, io__state, io__state).
:- mode io__putback_char(in, di, uo) is det.
% Un-reads a character from the current input stream.
@@ -166,24 +200,53 @@
% as a list of chars.
:- pred io__read_line_as_string(io__input_stream, io__result(string),
- io__state, io__state).
+ io__state, io__state).
:- mode io__read_line_as_string(in, out, di, uo) is det.
% Reads a line from specified stream, returning the
% result as a string.
-:- pred io__read_file(io__input_stream, io__result(list(char)),
- io__state, io__state).
+:- pred io__read_file(io__input_stream, io__maybe_partial_res(list(char)),
+ io__state, io__state).
:- mode io__read_file(in, out, di, uo) is det.
% Reads all the characters from the given input stream until
% eof or error.
-:- pred io__read_file_as_string(io__input_stream, io__res, string,
- io__state, io__state).
-:- mode io__read_file_as_string(in, out, out, di, uo) is det.
+:- pred io__read_file_as_string(io__input_stream,
+ io__maybe_partial_res(string), io__state, io__state).
+:- mode io__read_file_as_string(in, out, di, uo) is det.
% Reads all the characters from the given input stream until
% eof or error. Returns the result as a string rather than
% as a list of char.
+:- pred io__input_stream_foldl(io__input_stream, pred(char, T, T),
+ T, io__maybe_partial_res(T), io__state, io__state).
+:- mode io__input_stream_foldl(in, (pred(in, in, out) is det),
+ in, out, di, uo) is det.
+:- mode io__input_stream_foldl(in, (pred(in, in, out) is cc_multi),
+ in, out, di, uo) is cc_multi.
+% Applies the given closure to each character read from
+% the input stream in turn, until eof or error.
+
+:- pred io__input_stream_foldl_io(io__input_stream,
+ pred(char, io__state, io__state), io__res,
+ io__state, io__state).
+:- mode io__input_stream_foldl_io(in, (pred(in, di, uo) is det),
+ out, di, uo) is det.
+:- mode io__input_stream_foldl_io(in, (pred(in, di, uo) is cc_multi),
+ out, di, uo) is cc_multi.
+% Applies the given closure to each character read from
+% the input stream in turn, until eof or error.
+
+:- pred io__input_stream_foldl2_io(io__input_stream,
+ pred(char, T, T, io__state, io__state),
+ T, io__maybe_partial_res(T), io__state, io__state).
+:- mode io__input_stream_foldl2_io(in, (pred(in, in, out, di, uo) is det),
+ in, out, di, uo) is det.
+:- mode io__input_stream_foldl2_io(in, (pred(in, in, out, di, uo) is cc_multi),
+ in, out, di, uo) is cc_multi.
+% Applies the given closure to each character read from
+% the input stream in turn, until eof or error.
+
:- pred io__putback_char(io__input_stream, char, io__state, io__state).
:- mode io__putback_char(in, in, di, uo) is det.
% Un-reads a character from specified stream.
@@ -1460,19 +1523,18 @@
io__read_file(Stream, Result) -->
io__read_file_2(Stream, [], Result).
-:- pred io__read_file_2(io__input_stream, list(char), io__result(list(char)),
- io__state, io__state).
+:- pred io__read_file_2(io__input_stream, list(char),
+ io__maybe_partial_res(list(char)), io__state, io__state).
:- mode io__read_file_2(in, in, out, di, uo) is det.
io__read_file_2(Stream, Chars0, Result) -->
io__read_char(Stream, Result0),
(
{ Result0 = eof },
- { list__reverse(Chars0, Chars) },
- { Result = ok(Chars) }
+ { Result = ok(list__reverse(Chars0)) }
;
{ Result0 = error(Err) },
- { Result = error(Err) }
+ { Result = error(list__reverse(Chars0), Err) }
;
{ Result0 = ok(Char) },
io__read_file_2(Stream, [Char|Chars0], Result)
@@ -1480,11 +1542,11 @@
%-----------------------------------------------------------------------------%
-io__read_file_as_string(Result, String) -->
+io__read_file_as_string(Result) -->
io__input_stream(Stream),
- io__read_file_as_string(Stream, Result, String).
+ io__read_file_as_string(Stream, Result).
-io__read_file_as_string(Stream, Result, String) -->
+io__read_file_as_string(Stream, Result) -->
%
% check if the stream is a regular file;
% if so, allocate a buffer according to the
@@ -1510,7 +1572,14 @@
Buffer, Pos, BufferSize),
{ require(Pos < BufferSize, "io__read_file_as_string: overflow") },
{ io__buffer_to_string(Buffer, Pos, String) },
- io__check_err(Stream, Result).
+ io__check_err(Stream, Result0),
+ {
+ Result0 = ok,
+ Result = ok(String)
+ ;
+ Result0 = error(Error),
+ Result = error(String, Error)
+ }.
:- pred io__read_file_as_string_2(io__input_stream, buffer, int, int,
buffer, int, int, io__state, io__state).
@@ -1536,6 +1605,62 @@
Buffer, Pos, Size)
).
+%-----------------------------------------------------------------------------%
+
+io__input_stream_foldl(Pred, T0, Res) -->
+ io__input_stream(Stream),
+ io__input_stream_foldl(Stream, Pred, T0, Res).
+
+io__input_stream_foldl(Stream, Pred, T0, Res) -->
+ io__read_char(Stream, CharResult),
+ (
+ { CharResult = ok(Char) },
+ { Pred(Char, T0, T1) },
+ io__input_stream_foldl(Stream, Pred, T1, Res)
+ ;
+ { CharResult = eof },
+ { Res = ok(T0) }
+ ;
+ { CharResult = error(Error) },
+ { Res = error(T0, Error) }
+ ).
+
+io__input_stream_foldl_io(Pred, Res) -->
+ io__input_stream(Stream),
+ io__input_stream_foldl_io(Stream, Pred, Res).
+
+io__input_stream_foldl_io(Stream, Pred, Res) -->
+ io__read_char(Stream, CharResult),
+ (
+ { CharResult = ok(Char) },
+ Pred(Char),
+ io__input_stream_foldl_io(Stream, Pred, Res)
+ ;
+ { CharResult = eof },
+ { Res = ok }
+ ;
+ { CharResult = error(Error) },
+ { Res = error(Error) }
+ ).
+
+io__input_stream_foldl2_io(Pred, T0, Res) -->
+ io__input_stream(Stream),
+ io__input_stream_foldl2_io(Stream, Pred, T0, Res).
+
+io__input_stream_foldl2_io(Stream, Pred, T0, Res) -->
+ io__read_char(Stream, CharResult),
+ (
+ { CharResult = ok(Char) },
+ Pred(Char, T0, T1),
+ io__input_stream_foldl2_io(Stream, Pred, T1, Res)
+ ;
+ { CharResult = eof },
+ { Res = ok(T0) }
+ ;
+ { CharResult = error(Error) },
+ { Res = error(T0, Error) }
+ ).
+
%-----------------------------------------------------------------------------%
:- pred io__clear_err(stream, io__state, io__state).
Index: tests/general/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/general/Mmakefile,v
retrieving revision 1.35
diff -u -u -r1.35 Mmakefile
--- tests/general/Mmakefile 19 Dec 2001 02:53:47 -0000 1.35
+++ tests/general/Mmakefile 14 Jan 2002 08:08:20 -0000
@@ -37,6 +37,7 @@
higher_order \
intermod_type \
interpreter \
+ io_foldl \
io_regression \
liveness \
liveness2 \
@@ -119,6 +120,10 @@
-e 's/require.m:[0-9]*/require.m:NNNN/g' \
-e 's/exception.m:[0-9]*/exception.m:NNNN/g' \
| tr -d '\r' > string_format_test_3.out
+
+ # io_foldl `cat's its input to its output.
+io_foldl.out: io_foldl io_foldl.exp
+ ./io_foldl < io_foldl.exp > io_foldl.out 2>&1
#-----------------------------------------------------------------------------#
Index: tests/general/io_foldl.exp
===================================================================
RCS file: tests/general/io_foldl.exp
diff -N tests/general/io_foldl.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/general/io_foldl.exp 14 Jan 2002 05:43:37 -0000
@@ -0,0 +1,24 @@
+First 0x20 characters of fig 1.4 in MG are
+`In the beginning there was the t'.
+First 0x1b characters of fig 1.4 in MG are
+`In the beginning there was '.
+First 0x25 characters of fig 1.4 in MG are
+`In the beginning there was the text, '.
+
+Following line should have 3, 4, 1 significant figures.
+Strangly, 1.00e+01+ 10.000= 2E+01
+
+
+!%0 10.5i!%0+10.5i!%0 -10.5i!%0+-10.5i!
+!% 10.5i!%+10.5i!% -10.5i!%+-10.5i!
+!% 10.5x!%+10.5x!% -10.5x!%+-10.5x!
+!%#10.x!%#+10.x!%#-10.x!%#+-10.x!
+
+! -00031! -00031!-00031 !-00031 !
+! 00031! +00031! 00031 !+00031 !
+! -00031! -00031!-00031 !-00031 !
+! 00031! +00031! 00031 !+00031 !
+! ffffffe1! ffffffe1!ffffffe1 !ffffffe1 !
+! 0001f! 0001f!0001f !0001f !
+!0xffffffe1!0xffffffe1!0xffffffe1!0xffffffe1!
+! 0x1f! 0x1f!0x1f !0x1f !
Index: tests/general/io_foldl.m
===================================================================
RCS file: tests/general/io_foldl.m
diff -N tests/general/io_foldl.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/general/io_foldl.m 14 Jan 2002 08:00:40 -0000
@@ -0,0 +1,15 @@
+:- module io_foldl.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module require.
+
+main -->
+ io__input_stream_foldl_io(io__write_char, Res),
+ { require(unify(Res, ok), "Error reading file.") }.
Index: tests/general/io_regression.m
===================================================================
RCS file: /home/mercury1/repository/tests/general/io_regression.m,v
retrieving revision 1.1
diff -u -u -r1.1 io_regression.m
--- tests/general/io_regression.m 11 Sep 2000 04:28:22 -0000 1.1
+++ tests/general/io_regression.m 14 Jan 2002 07:44:06 -0000
@@ -13,8 +13,8 @@
:- implementation.
main -->
- io__read_file_as_string(Res, Str),
- ( { Res = ok } ->
+ io__read_file_as_string(Res),
+ ( { Res = ok(Str) } ->
io__write_string(Str)
;
io__write_string("Error reading file.\n")
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list