Working with the Local System
Whether you’re writing desktop applications or cloud native services, at one point or another you’re going to need to interact with the environment that your program is running in. Learning how to interact with the local system will let you write more useful programs that work with files, environment variables, and accept user input.
You’ll learn how to write an interactive application that reads data from standard input, reads files from disk, and makes use of environment variables to configure how the program runs. Importantly, in this chapter you’ll learn patterns for how to think about IO heavy pure functional programs.
After you’ve read this chapter you’ll be able to write traditional command line applications that deal with input and output. You’ll also be able to think through how to structure programs to handle different types of IO while maximizing the benefits that you get from working in a pure functional language.
In the next chapter you’ll build on the knowledge you’ve gained learning how to use IO to work with the local system when you learn about the Functor, Applicative, and Monad typeclasses. These typeclasses form the basis for how IO works in Haskell. By starting with a concrete understanding of one instance of how these typeclasses work, you’ll be better prepared to extend that knowledge to the more general case.
Handling Terminal Size Edge Cases
In our getTerminalSize
function there were several potential bugs that could
have occurred. Try address these edge cases:
tput
is missingtput
doesn’t return a numbertput
output doesn’t contain a trailing newline
Hint 1
Some high level hint text
Hint 2
Some more detailed hint text
Hint 3
Even more detailed hint text
Solution
A complete solution for the exercise
Do-ing Some Refactoring
Throughout most of this chapter we used bind syntax to implement our IO actions. Look through some of the code you’ve written for opportunities to refactor this application to use do-notation where appropriate.
Hint 1
Some high level hint text
Hint 2
Some more detailed hint text
Hint 3
Even more detailed hint text
Solution
A complete solution for the exercise
Refactoring to use Text and Bytestring
Many of the earlier exercises in this book used String
instead of ByteString
or Text
. Refactor some of your existing code to use these more efficient types
instead.
Hint 1
Some high level hint text
Hint 2
Some more detailed hint text
Hint 3
Even more detailed hint text
Solution
A complete solution for the exercise
Viewing Multiple Files
Expand your application to allow the user to pass more than one file in on the command line, and view them in order. Make sure to update the status line when you go from showing one file to another.
Hint 1
Some high level hint text
Hint 2
Some more detailed hint text
Hint 3
Even more detailed hint text
Solution
A complete solution for the exercise
Scrolling Backwards
Instead of just scrolling forward, update your application to allow the user to scroll backwards as well.
Hint 1
Some high level hint text
Hint 2
Some more detailed hint text
Hint 3
Even more detailed hint text
Solution
A complete solution for the exercise
Adding A Help Screen
Allow the user to view help text on how to use the program by entering ?
while
viewing a file. The program should clear the screen and display a help
message. Once the user scrolls past the end of the help text, or presses q
the
program should return them to where they were in the document.
Hint 1
Some high level hint text
Hint 2
Some more detailed hint text
Hint 3
Even more detailed hint text
Solution
A complete solution for the exercise
Terminal Resizing
Sometimes users will want to resize their terminals while viewing a document. This is a problem for our pager since we calculate the size of the terminal exactly once at the start of the program. Update your program to allow the user to resize the terminal while retaining their current place in the document (the first word on the screen before resizing should still be the first word on the screen after resizing, regardless of how much the screen space has increased or decreased).
Note that detecting changes to the size of the terminal automatically will be unreasonably difficult with the knowledge that you have learned so far in this book, so you should handle terminal resizing by allowing the user to press a key to reflow the text.
Hint 1
Some high level hint text
Hint 2
Some more detailed hint text
Hint 3
Even more detailed hint text
Solution
A complete solution for the exercise