A collection of short Haskell examples exploring functions, folds, recursion, state, parsing, concurrency, and related techniques.
Package metadata lives in Cabal, while day-to-day workflows are driven by GNU Make and Stack.
Haddock API documentation is available on:
(See also benchmark reports below.)
The repository contains both library modules under src/ and runnable example
programs under app/. Use make help to list the available development
targets.
Install the required tools first: stack, cabal, stylish-haskell,
cabal-fmt, hlint, hasktags, and yamllint.
For an overview of the available automation targets, run:
make helpTo initialise local Cabal configuration and update dependencies, run:
make setupTo build the project, run:
make buildTo run the default local workflow, run:
make defaultThis performs formatting, checks, and tests.
For the full workflow, including documentation, benchmarks, and executable examples, run:
make allFormat and style code using:
make formatThis runs:
cabal-fmt --inplace Scrapbook.cabal
stylish-haskell --inplace <all Haskell sources>To only perform code checks, run:
make checkThis runs tags and lint:
hasktags --ctags --extendedctag <all Haskell sources>
hlint --cross --color --show <all Haskell sources>
cabal check
yamllint --strict <tracked YAML files>To start a REPL with the project loaded, use:
stack replUsing Cabal also works for the REPL:
cabal replTest using GNU Make:
make testThis runs:
stack test --fastThe Criterion benchmark HTML reports can be generated using stack. They are available from GitHub, here:
- Criterion benchmarks:
To run individual benchmark:
stack bench Scrapbook:bench:polydivisorsBenchThe make bench target writes HTML reports to .stack-work/.
To generate Haddock for source:
make docThis runs stack haddock.
counter: count up and down from a natural number.fpcomplete: functor and contravariant-style examples based on function mapping.json: decode JSON with a variable top-level key.numberlines: number the lines of a file, similar tonl(1).polydivs: search for poly-divisible numbers.quine: print the program's own source.readfile: read a file using explicit handle management.skips: generate every nth element from an input list.stategame: small stateful game with score tracking.threads: simple STM andforkIOexample.vocab: extract and count distinct words from a file.while: implement awhileloop as a higher-order function.wordcount: count words in a file.wordcountarrow: count words using arrow-based composition.
ApplyToTuple: rank-N type example applying one function to two list types.BinarySearch: binary search over an ordered list.Caesar: Caesar cipher over a printable ASCII subset.CFold: continuation-passing fold implementation.Colours: semigroup example for colour mixing.CountEntries: count directory entries with several monadic approaches.Cps: continuation-passing style examples usingContandcallCC.Expr: small typed expression evaluator built with GADTs.Fractions: add fractions usingData.Ratio.HarmonicOscillation: simulate harmonic motion with theStatemonad.Lower: validate and construct lowercase alphabetic characters.Mod35: test whether a number is divisible by 3 or 5.MyFilter: implementfilterwithfoldr.MyFreeMonad: arithmetic DSL built with a free monad.MyJson: decode JSON containing special characters.MyPenultimate: return the second-to-last list element.MyReverse: reverse a list withfoldl,foldr, and recursion.MyState: small custom state type withget,put, andmodify.MySum: sum integers using local mutable state inST.MyTake: simpletakereimplementation.MyType: examples using type applications andTypeable.Permutation: generate permutations with several algorithms.PolyDivisors: poly-divisible number search used by the executable and benchmarks.Qsort: quicksort implementation.Random: random values and dice-roll style examples.RecursionSchemes: examples of anamorphisms, catamorphisms, and related folds.RepMax: replace every list element with the maximum value.SplitList: split lists and derive related helper functions.Stack: stack operations layered overMyState.STy: internal singleton-type example forBool,Int, andMaybe.SubSeqs: generate subsequences with multiple algorithms.TermFold: fold with early termination.Trim: trim whitespace with fold-based implementations.Weekday: weekday enumeration and string conversion helpers.Yahtzee: enumerate Yahtzee roll choices.ZipFold: zip two lists using a fold-based representation.
Notes on using ghcid.
cabal update
cabal install ghcidThen copy executable to $HOME/.local/bin/.
For example to monitor changes for one file app/Threads.hs call:
ghcid -l -c 'ghci -package stm app/Threads.hs'If no errors, then the screen will report something like:
All good (1 module, at 21:28:27)
Alternatively, to monitor a couple of files:
ghcid -l src/Weekday.hs test/WeekdaySpec.hsTo monitor the entire project, use:
ghcid -lTo monitor a couple of files (as per above):
:let g:ghcid_args="--lint src/Weekday.hs test/WeekdaySpec.hs"
:GhcidStart
To stop, call:
:GhcidStop
See also vim-ghcid plugin.
When editing using Visual Studio Code, use GHCup.
To show available software versions:
ghcup tuiTo show current installation:
ghcup listExample output:
$ ghcup list -c installed
Tool Version Tags Notes
✔✔ ghc 9.6.7 recommended,base-4.18.3.0 hls-powered
✔✔ cabal 3.12.1.0 recommended
✔✔ hls 2.10.0.0 latest,recommended
✔✔ stack 3.5.1 latest
✔✔ ghcup 0.1.50.2 latest,recommended