<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">I am writing code lately that is heavily dependant upon the successful reading of a file, finding something in that that file, opening an input stream on a file, opening an output stream on that file and a few more key decisions before the actual file processing can begin.<div class=""><br class=""></div><div class="">The first incarnation of my code has thus suffered from what is often called 'stair-casing' where each nested disjunction is creeping the code more and more to the right.</div><div class=""><br class=""></div><div class="">So I refactored some code to bring it back into line but now I have lots of predicates... </div><div class=""><br class=""></div><div class="">I guess what I am trying to ask is, is there a 'Mercury Way' to handling this. Haskell has the Maybe monad which can greatly help to chain operations, is there a similar thing with Mercury ? In my transpiler, I had this issue and I created a small structure that each successive</div><div class=""><br class=""></div><div class="">:- type control ---> control(...);</div><div class=""><div class="">:- pred step1(control::in, control::out) is det.</div></div><div class=""><div class="">:- pred step2(control::in, control::out) is det.</div></div><div class=""><div class="">:- pred step3(control::in, control::out) is det.</div></div><div class=""><br class=""></div><div class="">some [!C] (</div><div class=""> !:C = control(...),</div><div class=""> step1(!C),</div><div class=""> step2(!C),</div><div class=""> step3(!C)</div><div class="">)</div><div class=""><br class=""></div><div class="">This feels cleaner but again, would this be the 'right' thing to do in Mercury. I am much better with the language now than a year ago, almost to the point of not having to think too hard now about anything other than the problem, which is great!</div><div class=""><br class=""></div><div class="">The only other code I've seen that inspired me to what may be possible is in the implementation of a "/" operator which takes in a pred() and returns a pred(), this code is from config.m of mmc-doc (such a useful program!)...</div><div class=""><br class=""></div><div class=""><font face="LektonNerdFontCompleteM-Regular" class="">:- type maybeio == (pred(maybe(string), io, io)).</font></div><font face="LektonNerdFontCompleteM-Regular" class="">:- inst maybeio == (pred(out, di, uo) is det).<br class="">:- func (maybeio::in(maybeio)) // (maybeio::in(maybeio))<br class=""> = (maybeio::out(maybeio)).<br class="">A // B = C :-<br class=""> C = (pred(Res::out, !.IO::di, !:IO::uo) is det :-<br class=""> A(Res1, !IO),<br class=""> (<br class=""> Res1 = Res @ yes(_)<br class=""> ;<br class=""> Res1 = no,<br class=""> B(Res, !IO)<br class=""> )).</font><div class=""><br class=""><div class="">I guess that, with lots of smaller predicates, the skill comes with choosing meaningful names and writing clear code, principles applicable to any development project.</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Sean.</div><div class=""><br class=""></div></div></body></html>