let main () : unit Deferred.t =
(* First up, we create a Reader.t from stdin. Luckily, the Reader module has
* exactly this already! The only hiccup is that Reader.stdin is of type
* `Reader.t Core.Std.Lazy.t`. It's not too important what that means; all we
* have to do is call Lazy.force to get the Reader.t we're looking for. *)
let stdin = Lazy.force Reader.stdin in
(* The Reader module has a lot of functions to read from a Reader.t:
* Reader.read, Reader.read_char, Reader.really_read, etc. For now, we just
* want to read a single from the user, so we'll use Reader.read_line. As
* the name suggests, it reads all the data up to and including the newline
* character.
*
* Of course, reading could go wrong. For example, we could read from a file
* that's been deleted or read from a TCP connection that's been closed. So,
* Reader.read_line, and all the other reading functions in the Reader
* module, return a Read_result.t. A Read_result.t is either `Eof (signifying
* we've hit the end of the reader) or an `Ok x, where the x is the data
* we're after. If our read here doesn't work, we'll just print "error".
* Otherwise, we'll print whatever line the user typed in. *)
Reader.read_line stdin >>| function
| `Eof -> print_endline "error"
| `Ok x -> print_endline x