A Complete Data Family Based ShellCommand
Use what you’ve learned in this chapter to add interactive spellchecking to the HCat application you built earlier in this book, when learning about IO
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
Better If Expressions
Earlier in the chapter you implemented conditionals inside of type families
using IfThenElse
. Instead of making this a single type family, try to use a
mixture of GADTs and Type Families to explore other ways to encode conditionals
that give you more flexibility, or more closely resemble term level
conditionals.
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
Type Level Map
Write a type family named Map
that works like the term level map
function. It should allow you to apply a function to each element of a type
level list. Next, add a new type or type family so that you can add a number to
each element of a type level list of naturals, as in this example:
:kind! Map (Add 5) [0,1,2,3,4]
λ Map (Add 5) [0,1,2,3,4] :: [Natural]
= '[5, 6, 7, 8, 9]
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
Expanded Shell Commands
Expand the GADT based shell command DSL to support a new operation, wc
that
will call the wc
program to count the number of lines in a file. After you’ve
added that, write a function with the type:
countLinesInMatchingFiles :: String -> ShellCmd FilePath [(FilePath, Int)]
The function should take a glob that can be passed to grep
, and it should
return a shell command that, given a path to a directory full of files, will
output the name of each file that matched with grep
, along with the number of
lines in that file. Be sure to only return one output for each file, even if
there are multiple matches within the file.
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
Classless runScript
Using what you’ve learned in this chapter, experiment with other ways of
defining CommandSet
and runScript
so that you don’t need to use type
classes. What are the trade-offs you need to make?
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
Capstone Project: Build a Terminal Multiplexer
A terminal multiplexer is an application that lets you run different terminal
applications simultaneous. The multiplexer typically gives you tools to switch
between different “screens” displaying the output of different
applications. They may also allow you to configure a set of applications to open
automatically at startup. screen
and tmux
are two popular terminal
multiplexers that you can look at for inspiration.
Using everything that you’ve learned in this book, write your own application
that integrates a terminal multiplexer capability. For example, you might want
to re-implement the hcat
project that you built in the middle of this book,
this time allowing users to open multiple files and switch between them, or even
show multiple files side by side. Design your library so that a user writing
their own terminal application can easily use your multiplexer to add their own
layout and contents.
This is a large project. You will need to use most of what you’ve learned in this book, and you’ll need to learn new libraries and dive into areas we haven’t covered in this book, like multi-threaded programming. You can make this project as large, or small as you want. Whatever you decide, have fun with it! Build something for yourself, use it, improve it, and update it with new versions of GHC as they are released. A living project that you can use every day will give you the best possible experience of how to build and maintain effective Haskell code.
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