Language basics
27 steps in 9 sets of Haskell.
Haskell is the language where the type system does the heavy lifting: pure functions by default, effects marked in the types, and a compiler that catches whole categories of bugs before anything runs. It reads less like instructions and more like definitions — a program is a set of equations, and GHC figures out how to run them lazily, only as results are demanded.
This tour covers the working core in plain GHC2021 — no extensions: bindings with signatures, currying and composition, pattern matching with guards, lists and comprehensions, the map/filter/fold trio, algebraic data types and records, typeclasses with deriving and hand-written instances, and just enough do-notation to print results. The encore ships complete programs. Every seed typechecks under ghc -Wall with warnings as errors, and the encore runs start to finish.
Values & types
- Bindings & signaturesA trail profile written as top-level bindings, each with its own type signature.
- Integer and fractional mathBrews cups from a bag of beans, keeping whole-number and fractional math apart.
- Strings and charsReshapes a gate announcement, since a
Stringis just a list of characters.
Functions
- Defining functionsA shipping quote assembled from two small functions and a literal pattern.
- Currying & partial applicationA tip calculator that hands out half-applied functions instead of numbers.
- Composition & pipelinesCounts words two ways, putting point-free and pointed style side by side.
Pattern matching
- case and list shapesReads a corridor of traffic signals with
caseexpressions over a sum type. - Guards and whereTurns a term of exam scores into a letter grade with a note attached.
- Tuples and pairsPairs seat rows with ticket counts, then picks out the busiest row.
Lists
- Building lists
(:)adds one element to the front,(++)joins two whole lists, and a pattern covers the empty case. - Ranges
[6 .. 10]counts up by one; naming the first two elements picks any other step. - List comprehensionsGenerators on the right of the bar feed the expression on the left, and guards drop what fails.
Higher-order
- map & filter
maprewrites every element,filterkeeps the ones that pass, and(.)chains the two into a pipeline. - Folds
foldrandfoldl'both collapse a list to one value; they differ in direction and in when work happens. - Lambdas & sectionsA lambda is a function with no name; a section is an operator with one operand already filled in.
Types & records
- Sum typesA sum type lists every value the type can hold, and
derivingwrites the printing and comparison code. - RecordsRecord syntax names each field, defines an accessor per field, and copies a value with changes.
- Maybe & Either
Maybereports a missing value asNothing;Eithercarries a reason on theLeft.
Typeclasses
- Deriving instancesA
derivingclause on a sum type supplies Show, Eq, Ord, Enum, and Bounded for free. - Custom instancesHand-written
ShowandEqinstances decide how a value prints and what counts as equal. - Ord and sortingThree orderings of one list:
sortBywith a comparator,sortOnwith a key, andDownto reverse.
IO basics
- Sequencing IO with doA
doblock runs IO actions top to bottom, calling a pure helper partway through. - let versus bind in IOInside
do,letnames a pure value while<-runs an action and binds its result. - Printing with mapM_
mapM_runs an action per element and drops the results;forM_is the same with flipped arguments.
Encore
- word_freq.hsCounts word frequencies across an inline passage and prints the top eight with totals.
- grade_report.hsAverages each student's scores, assigns a letter grade, and prints a ranked table with a class summary.
- temp_stats.hsReports a week of daily highs with the low, high, mean, and a bar chart beside each day.