Haskell Cheatsheet
Types and Signatures
Use this Haskell reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Type Signatures
square :: Int -> Int square x = x * x hypotenuse :: Double -> Double -> Double hypotenuse a b = sqrt (a * a + b * b)
Read a -> b -> c as a function that takes a, then b, then returns c. All Haskell functions technically take one argument because functions are curried.
Type Inference
Haskell infers types, but explicit signatures are still recommended for top-level functions.
triple x = x * 3 -- ghci: :type triple -- triple :: Num a => a -> a
Num a => is a constraint: the type a must support numeric operations.
Constraints in Practice
showAll :: Show a => [a] -> String showAll = unwords . map show between :: Ord a => a -> a -> a -> Bool between lo hi x = lo <= x && x <= hi sumAny :: (Foldable t, Num a) => t a -> a sumAny = sum
Multiple constraints go in a parenthesized tuple before =>.
Common Typeclasses
| Typeclass | Meaning | Examples |
|---|---|---|
Eq | equality | ==, /= |
Ord | ordering | <, >, compare |
Show | convert to string | show x |
Read | parse from string | read "123", readMaybe |
Num | numeric operations | +, *, abs |
Integral | whole numbers | div, mod |
Fractional | division | /, recip |
Semigroup | associative combine | <> |
Monoid | combine with identity | mempty, mconcat |
Functor | map inside context | fmap, <$> |
Foldable | reduce a structure | foldr, sum, toList |
Traversable | map with effects | traverse, sequenceA |
Applicative | apply wrapped functions | <*>, pure |
Monad | sequence dependent actions | >>=, do |
Type Synonyms
type UserId = Int type Name = String formatUser :: UserId -> Name -> String formatUser uid name = show uid ++ ": " ++ name
A type synonym improves readability but does not create a distinct runtime type. Use newtype when you want the compiler to keep types apart.
Conversions
fromIntegral (length xs) :: Double -- Int to any Num realToFrac (3.2 :: Float) :: Double show 42 -- "42" round 3.7 -- 4 floor 3.7 -- 3 ceiling 3.1 -- 4 truncate (-3.7) -- -3, toward zero
Parsing: read vs readMaybe
import Text.Read (readMaybe) read "42" :: Int -- 42, but CRASHES on bad input readMaybe "42" :: Maybe Int -- Just 42 readMaybe "4x" :: Maybe Int -- Nothing read @Int "42" -- TypeApplications form (on by default in GHC2021)
read is partial. Any time the input can be invalid (user input, files, network), use readMaybe and handle the Nothing case.