Applied Haskell is a commercial training program focusing on teaching intermediate Haskell. The goal is to help someone move from knowing Haskell basics to being able to write commercial software, with enough knowledge to pick up any new skills needed on demand.
If you're new to Haskell, please check out our learning page for introductory material.
The content below is freely available. If you're interested in participating in a class teaching this material, please check out our training page.
If you're not participating in a instructor-led course, feel free to skip this section.
This course is typically taught over a two day period by an FP Complete Haskell engineer. There is more material available here than can be taught in two days, so some content is typically skipped in the classroom, with student interest guiding what we focus on. This course also has a one day subset.
In order to maximize the value of this course, we strongly recommend that you:
- Ensure you meet the prerequisites mentioned below
- Set up your system before attending the class following the instructions below
- At least skim through the material below before the course
- Perform the exercises during the course
- Take time after the course to review the material again and take another crack at any exercises you were not successful at
You should already be comfortable with Haskell syntax, common control structures, and typeclasses. For the most part: if you understand how to use monads, you're ready for this course. Though we'll cover it in more detail during the course, you should also read all about strictness, as experience has shown this to be a topic that trips people up often.
As a self test, we recommend you to go through this Functor, Applicative and Monad tutorial and solve the exercises in it.
If you're looking to read up and learn Haskell from scratch, our recommendation is Haskell Programming from First Principles for a thorough coverage of all relevant topics.
Let the course material begin!
We will be using the Stack build tool extensively throughout this course. To get your system set up:
Download and install Stack following our Getting Started guide. If you already have Stack installed, run
stack upgradeto ensure you have the latest version.
We're going to be using LTS Haskell version 12.21. (We'll explain what LTS Haskell is in the material below.) You may as well install an unnecessarily broad number of packages right off the bat:
$ stack build --resolver lts-12.21 classy-prelude-yesod lens rio yesod-test foldl microlens-platform wai-conduit hspec`
- You may also find it convenient to run
stack config set resolver lts-12.21from outside of a project to set your global resolver to match.
- You may also find it convenient to run
Make sure you can run the script below successfully. Save it to a file ending with
.hsand then run
stack filename.hs. On non-Windows systems, you can also do
chmod +x filename.hs && ./filename.hs
#!/usr/bin/env stack -- stack --resolver lts-12.21 script main = putStrLn "Hello World!"
Note that the comment on line 2 above is necessary!
Applied Haskell 101
We'll start off with a high level overview of the content we're going to cover, our approach to Haskell, and tooling to be aware of.
The RIO approach
rio library codifies much of our recommended best practices. It
includes an approach to structuring applications, a standard library,
a Prelude replacement, and more.
Mutability and concurrency
Haskell is immutable-by-default, but that default can be overridden. And this mutability often pops up in the context of concurrency. This is one of Haskell's greatest strengths, and we'll cover it now.
Strictness, laziness, and evaluation
One of the hallmarks of Haskell is lazy evaluation. Understanding how this works, when to use strictness, and how to avoid space leaks are vital to production quality Haskell code.
Lists are a common data structure in Haskell, but they are often overused. It's vital to understand other common data structures. This section intentionally comes after the strictness section, as the former is a prerequisite for this material.
- Data Structures
- String Types
- Builders and difference lists
- Let's revisit that data structure quiz...
Exceptions are built into the Haskell runtime. Proper handling is essential.
- Safe exception handling—sufficient for most Haskell users
- Asynchronous Exception Handling in Haskell—deeper dive into understanding the exception system
You must test your code. Haskell strong types help immensely, but they are not a replacement for testing. Fortunately, Haskell has great testing libraries and tools.
Serialization to external binary and text-based formats.
Standard programming needs
- typed-process for launching and interacting with subprocesses
- HTTP client library
- Web services
- Command line argument parsing optparse-applicative
- Random number generation
Deeper understanding of Haskell performance, and how to improve it.
This section demonstrates some common Haskell coding patterns, how they work, when they're useful, and possible pitfalls.
- Covariance, contravariance, and positive and negative position
- Continuation Passing Style
- Constraint trick for instances; perhaps we can have a section for common type patterns (newtypes an obvious one, and also for example using Rank-N types to store a generic function in a data structure, versus existential types to store generic data).