[m-users.] Instantiatedness and handling io results
Julian Fondren
jfondren at minimaltype.com
Sun Aug 4 19:37:10 AEST 2019
On 2019-08-04 03:38, Julian Fondren wrote:
> On 2019-08-04 02:48, Philip White wrote:
>> 2. What is the idiomatic way of handling a sequence of things which
>> return results? In Haskell, there is do-notation for sequencing
>> monads,
>> but I haven't seen any monads in mercury.
>
> I don't expect you to agree, but the xkcd joke about regular
> expressions is how I think about Haskell solutions to problems.
Try the following out.
And then, change 'semidet_from_char_list' to 'from_char_list' in main/2,
and try and understand the resulting error message.
:- module readtwo4.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module string, list, maybe, char.
main(!IO) :-
Read = read_word
>> semidet_from_char_list
>> to_int
// die("bad read"),
Read(N, !IO),
Read(M, !IO),
foldl(io.write_line, (N .. M), !IO).
:- pred die(string::in) is erroneous.
:- pragma foreign_proc("C",
die(Reason::in),
[promise_pure, will_not_call_mercury],
"
puts(Reason);
exit(1);
").
%------------------------------------------------------------%
% / \
% | () () |
% \ ^ /
% |||||
% |||||
%------------------------------------------------------------%
:- type producer(T) == (pred(T, io, io)).
:- inst producer == (pred(out, di, uo) is det).
:- type resulter(T) == producer(io.result(T)).
:- inst resulter == producer.
:- type transformer(A, B) == (pred(A, B)).
:- inst transformer == (pred(in, out) is semidet).
:- type effect == (pred).
:- inst effect == ((pred) is erroneous).
:- func resulter(A) >> transformer(A, B) = resulter(B).
:- mode in(resulter) >> in(transformer) = out(resulter).
R1 >> T = R2 :-
R2 = (pred(Res::out, !.IO::di, !:IO::uo) is det :-
R1(Res0, !IO),
(
Res0 = ok(X1),
( if T(X1, X2) then
Res = ok(X2)
else
Res = error(make_io_error("transformation failed"))
)
;
Res0 = eof,
Res = eof
;
Res0 = error(E),
Res = error(E)
)).
:- func resulter(T) // effect = producer(T).
:- mode in(resulter) // in(effect) = out(producer).
R // E = P :-
P = (pred(Res::out, !.IO::di, !:IO::uo) is det :-
R(Res0, !IO),
( if Res0 = ok(Res1) then
Res = Res1
else
E
)).
More information about the users
mailing list