Haskell Cheatsheet

Basics

Use this Haskell reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Hello World

main :: IO ()
main = putStrLn "Hello, world!"

Run a single file with runghc Main.hs, compile with ghc -O2 Main.hs, or load it into ghci for interactive exploration. Use this Haskell cheatsheet alongside the online Haskell compiler and Haskell course when you need a quick functional programming reference.

Toolchain: GHCup, Cabal, Stack, HLS

Install everything through GHCup, the official toolchain manager. HLS (Haskell Language Server) powers editor support, for example the VS Code Haskell extension.

CommandPurpose
ghcup tuiinteractive terminal UI to install and switch versions
ghcup install ghc 9.10.1install a specific GHC
ghcup set ghc 9.10.1make it the default ghc on PATH
ghcup install cabalthe cabal build tool
ghcup install stackthe stack build tool
ghcup install hlsHaskell Language Server
ghc --version, cabal --versionverify the install

Project Commands

# cabal
cabal init          # scaffold a package (.cabal file)
cabal build         # compile
cabal run           # build and run the executable
cabal repl          # ghci with project dependencies loaded
cabal test          # run the test suite
cabal update        # refresh the Hackage package index

# stack (alternative build tool, pins a snapshot of package versions)
stack new myproj    # scaffold from a template
stack build
stack run
stack ghci
stack test

Dependencies go in the build-depends field of the .cabal file (or package.yaml with stack), for example build-depends: base, text, containers.

Comments and Layout

-- Single-line comment

{- Multi-line
   comment -}

area r = pi * r * r

Haskell uses layout instead of braces in normal code. Align definitions in a block at the same indentation level.

let x = 10
    y = 20
in x + y

Names and Operators

  • Variables and functions start lowercase: total, parseLine.
  • Types and constructors start uppercase: Maybe, Just, User.
  • Operators are functions: 1 + 2 is the same kind of call as (+) 1 2.
  • Use backticks to call a normal function infix: 10 div 3.
add x y = x + y
same = (+) 2 3
also = 10 `div` 3

Basic Values

answer :: Int
answer = 42

name :: String
name = "Ada"

letter :: Char
letter = 'A'

active :: Bool
active = True

Common numeric types: Int, Integer, Float, Double. Integer is arbitrary precision, Int is machine-sized.

String vs Data.Text

String is just [Char], a lazy linked list. It is fine for tiny scripts, but working code uses Text from the text package: compact, fast, and Unicode-correct. Enable OverloadedStrings so string literals can be Text.

{-# LANGUAGE OverloadedStrings #-}
import Data.Text (Text)
import qualified Data.Text as T

greeting :: Text
greeting = "hello"        -- a literal, thanks to OverloadedStrings

shout :: Text -> Text
shout = T.toUpper

fromString :: String -> Text
fromString = T.pack       -- T.unpack converts back to String

Common Text functions: T.length, T.words, T.lines, T.splitOn, T.strip, T.replace, T.intercalate, T.isPrefixOf. Library APIs that take String usually have a Text twin, reach for the Text one.

Language Editions and Extensions

Modern GHC defaults to the GHC2021 language edition, which already enables widely used extensions such as BangPatterns, TypeApplications, ScopedTypeVariables, NamedFieldPuns, ImportQualifiedPost, TupleSections, and the DeriveFunctor/DeriveFoldable/DeriveTraversable/DeriveGeneric family. GHC2024 additionally turns on LambdaCase, DataKinds, and DerivingStrategies. Anything else is enabled per file:

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE LambdaCase #-}
ExtensionWhy you want it
OverloadedStringsstring literals as Text or ByteString
OverloadedRecordDotuser.name field access (GHC 9.2+)
LambdaCase\case instead of \x -> case x of
RecordWildCardsUser{..} binds every field at once
DerivingStrategiesexplicit deriving stock/newtype/anyclass