@@ -101,6 +101,9 @@ <h2>Java 8 Examples</h2>
101101< li >
102102< p > < a href ="#optionMap "> Option map</ a > </ p >
103103</ li >
104+ < li >
105+ < p > < a href ="#ioWalkthrough "> IO Walkthrough</ a > </ p >
106+ </ li >
104107</ ul >
105108</ div >
106109</ div >
@@ -393,6 +396,89 @@ <h2 id="optionMap">Option Map</h2>
393396</ div >
394397</ div >
395398</ div >
399+ </ div >
400+ < div class ="sect1 ">
401+ < h2 id ="ioWalkthrough "> IO Walkthrough</ h2 >
402+ < div class ="sectionbody ">
403+ < div class ="paragraph ">
404+ < p > < a href ="https://github.com/functionaljava/functionaljava/blob/master/demo/src/main/java/fj/demo/IOWalkthrough.java "> Github Source</ a > </ p >
405+ </ div >
406+ < div class ="paragraph ">
407+ < p > Demonstrates how to work with the IO type.</ p >
408+ </ div >
409+ < div class ="listingblock ">
410+ < div class ="content ">
411+ < pre class ="prettyprint highlight "> < code class ="language-java " data-lang ="java "> // IO is just a container to defer a computation (lazy), with the intention
412+ // to encapsulate computations that either consume and/or produce side-effects
413+ // the computation is not (yet) executed on creation hence it can be treated
414+ // like a value
415+
416+ final IO<Unit> askName = () -> {
417+ System.out.println("Hi, what's your name?");
418+ return Unit.unit();
419+ };
420+
421+ // fj.data.IOFunctions contains a lot of convenience functions regarding IO, the
422+ // above example could be rewritten with IOFunctions.stdoutPrintln
423+ // we now create an IO value to prompt for the name if executed
424+
425+ IO<Unit> promptName = IOFunctions.stdoutPrint("Name: ");
426+
427+ // we can compose these two values with fj.data.IOFunctions.append, since they
428+ // both are not interested in any runtime value
429+
430+ IO<Unit> askAndPromptName = IOFunctions.append(askName, promptName);
431+
432+ // now we create an IO value to read a line from stdin
433+
434+ final IO<String> readName = () -> new BufferedReader(new InputStreamReader(System.in)).readLine();
435+
436+ // this is the same as IOFunctions.stdinReadLine()
437+
438+ // now we create a function which takes a string, upper cases it and creates
439+ // an IO value that would print the upper cased string if executed
440+
441+ final F<String, IO<Unit>> upperCaseAndPrint = F1Functions.<String, IO<Unit>, String>o(IOFunctions::stdoutPrintln).f(String::toUpperCase);
442+
443+ // we now want to compose reading the name with printing it, for that we need to
444+ // have access to the runtime value that is returned when the
445+ // IO value for read is executed, hence we use fj.data.IOFunctions.bind instead
446+ // of fj.data.IOFunctions.append
447+
448+ final IO<Unit> readAndPrintUpperCasedName = IOFunctions.bind(readName, upperCaseAndPrint);
449+
450+ // so append is really just a specialised form of bind, ignoring the runtime
451+ // value of the IO execution that was composed before us
452+
453+ final IO<Unit> program = IOFunctions.bind(askAndPromptName, ignored -> readAndPrintUpperCasedName);
454+
455+ // this is the same as writing IOFunctions.append(askAndPromptName, readAndPrintUpperCasedName)
456+
457+ // we have recorded the entire program, but have not run anything yet
458+ // now we get to the small dirty part at the end of our program where we actually
459+ // execute it
460+
461+ // we can either choose to just call program.run(), which allows the execution to escape
462+ // or we use safe to receive an fj.data.Either with the potential exception on the
463+ // left side
464+
465+ toSafeValidation(program).run().on((IOException e) -> { e.printStackTrace(); return Unit.unit(); });
466+
467+ // doing function composition like this can be quite cumbersome, since you will end
468+ // up nesting parenthesis unless you flatten it out by
469+ // assigning the functions to variables like above, but you can use the fj.F1W
470+ // syntax wrapper for composing single-argument functions and fj.data.IOW
471+ // for composing IO values instead, the entire program can be written like so:
472+
473+ IOW.lift(stdoutPrintln("What's your name again?"))
474+ .append(stdoutPrint("Name: "))
475+ .append(stdinReadLine())
476+ .bind(F1W.lift((String s) -> s.toUpperCase())
477+ .andThen(IOFunctions::stdoutPrintln))
478+ .safe().run().on((IOException e) -> { e.printStackTrace(); return Unit.unit(); });</ code > </ pre >
479+ </ div >
480+ </ div >
481+ </ div >
396482</ div > </ p >
397483 </ article >
398484 </ div > <!-- /.col-md-12 -->
0 commit comments