Haskell Pure functional language

Version GHC 9.14.1 · source

Start here

ghci
Interactive REPL
ghc -O2 -o <out> Main.hs
Optimised build
runghc <file.hs>
Run a script
:t <expr>
Show a type in GHCi
:r
Reload changed modules
cabal run
Build and run
cabal repl
GHCi for the project
ghcup tui
Manage toolchains

Concepts

ghcup installs ghc, cabal, stack, hls
cabal or stack resolve packages, build, test
ghc compiles modules, ghci is its REPL
The toolchain: ghcup installs the compilers, a build tool drives them

GHC

ghc <file.hs>
Compile a program
Output goes next to the source.
ghc -o <out> <file.hs>
Name the executable
ghc -O2 <file.hs>
Optimise heavily
-O1 is the usual -O; the default is -O0.
ghc -Wall <file.hs>
Enable common warnings
ghc -e '<expr>'
Evaluate an expression and exit
ghc -c <file.hs>
Compile to an object file only
ghc --make Main.hs
Build all imported modules
Default when given source files.
ghc -i<dir> Main.hs
Add a module search directory
ghc -outputdir <dir> Main.hs
Put .o and .hi files elsewhere
ghc -threaded -rtsopts Main.hs
Threaded runtime with RTS flags
ghc -package <pkg> Main.hs
Expose a package
ghc -prof -fprof-auto Main.hs
Build with profiling
ghc -fno-code <file.hs>
Type-check only
ghc -XOverloadedStrings Main.hs
Enable a language extension
runghc <file.hs>
Run a source file directly

GHCi

ghci
Start the REPL
:l <file>
Load a module
:r
Reload the loaded modules
:t <expr>
Show the type of an expression
:i <name>
Show info on a name or class
:k <type>
Show the kind of a type
:q
Quit GHCi
Ctrl+D also works.
:browse <Module>
List what a module exports
:doc <name>
Show documentation for a name
:set +t
Print the type of each result
:m + <Module>
Bring a module into scope
:main <args>
Run main with arguments
:set -X<Ext>
Enable an extension
:! <cmd>
Run a shell command
let x = 5
Bind a name at the prompt
it
Result of the last expression

Cabal

cabal init
Create a package
cabal build
Build the targets
cabal run <exe>
Build and run an executable
Program arguments go after the target.
cabal test
Build and run test suites
cabal repl
GHCi with the package loaded
cabal update
Refresh the package index
cabal install <pkg>
Install an executable
cabal install --lib <pkg>
Add a library to the environment
cabal clean
Remove dist-newstyle
cabal haddock
Build API docs
cabal bench
Run benchmarks
cabal freeze
Pin solver versions
cabal list <text>
Search packages
cabal build --enable-profiling
Build with profiling
cabal run -- <args>
Separate program arguments

Stack and ghcup

stack new <name>
Create a project
stack build
Build the project
Fetches the snapshot's GHC if needed.
stack run
Build and run
stack test
Build and run tests
stack ghci
Open GHCi for the project
stack exec <cmd>
Run a command in Stack's environment
stack install <pkg>
Install an executable
stack clean
Delete build artefacts
stack path
Show Stack's locations
ghcup list
List available tools and versions
ghcup install ghc <ver>
Install a GHC version
ghcup set ghc <ver>
Select the active GHC
ghcup install cabal
Install cabal-install
ghcup upgrade
Update ghcup itself

Types and classes

f :: Int -> Int
Type signature
data T = A | B Int
Sum type with a constructor field
data P = P { x :: Int }
Record with field accessors
newtype N = N Int
Zero-cost wrapper type
type S = String
Type synonym
class C a where
Declare a typeclass
instance C T where
Implement a class for a type
deriving (Show, Eq, Ord)
Auto-generate instances
f :: (Show a) => a -> String
Constrain a type variable
Maybe a
Value that may be missing
Just x or Nothing.
Either e a
Success or failure
Left is the error by convention.
[a]
List of a
(a, b)
Tuple
IO a
Action that yields an a

Syntax

f 0 = 1; f n = n * f (n-1)
Pattern matching clauses
case m of Just x -> x
Pattern match an expression
f x | x > 0 = 1 | otherwise = 0
Guards
\x -> x + 1
Lambda
let y = 2 in y * 2
Local binding
f = g where g = 1
Bindings scoped to a definition
if c then a else b
Conditional, always needs else
do { x <- act; return x }
Do notation for monads
[x*2 | x <- xs, x > 1]
List comprehension
f . g
Compose functions
f $ g x
Apply with low precedence
xs !! 2
Index a list
import qualified Data.Map as M
Qualified import
-- note / {- note -}
Comments

Common functions

map f xs
Apply f to each element
filter p xs
Keep elements matching p
foldr f z xs
Right fold
foldl' f z xs
Strict left fold
From Data.List.
zip xs ys
Pair up two lists
fmap f m / f <$> m
Map inside a functor
mapM_ print xs
Run an action per element
maybe d f m
Fold a Maybe
either f g e
Fold an Either
read s :: Int
Parse a string
show x
Convert to a string
putStrLn s
Print a line
getLine
Read a line of input
sequence_ / traverse
Run structures of actions

Recipes

Hello program
main :: IO ()main = putStrLn "Hello"-- ghc -O2 -Wall -o hello Hello.hs
Handle a Maybe
safeDiv :: Int -> Int -> Maybe IntsafeDiv _ 0 = NothingsafeDiv a b = Just (a `div` b)main = print (safeDiv 4 2 >>= safeDiv 10)
Typeclass instance
data Color = Red | Green deriving (Eq, Show)class Pretty a where pretty :: a -> Stringinstance Pretty Color where  pretty Red = "red"  pretty Green = "green"
New cabal project
mkdir demo && cd democabal init --non-interactivecabal build && cabal runcabal repl