The Cheat Sheet
ContributeSearch
← LanguagesEdit this page

Haskell

Core Haskell syntax for functions, types, lists, pattern matching, algebraic data types, and type classes.

Variables and Functions

-- Bindings are immutable; this is a top-level definition
name :: String
name = "Ada"

-- Function: parameters then body
add :: Int -> Int -> Int
add a b = a + b

-- Function application is just juxtaposition with spaces
-- add 2 3   evaluates to 5

-- Single-argument functions
double :: Int -> Int
double x = x * 2
  • Bindings and functions are declared with name = value.
  • :: declares a type; a -> b is a function from a to b.
  • Function application uses spaces, not parentheses: f x y.

Currying and Composition

-- add 2 3 is (add 2) 3 — partial application
inc :: Int -> Int
inc = add 1

-- Composition
evenSquares :: [Int] -> [Int]
evenSquares = filter even . map (^ 2)
  • Functions are curried: they take one argument and return a function.
  • . composes functions right-to-left.

Lists

nums :: [Int]
nums = [1, 2, 3, 4]

-- Constructor (:) prepends; [] is empty
head nums          -- 1
tail nums          -- [2,3,4]
nums !! 0          -- 1
length nums        -- 4
sum nums           -- 10

-- Ranges
[1 .. 5]           -- [1,2,3,4,5]
[2, 4 .. 10]       -- [2,4,6,8,10]

-- Functions over lists
map (* 2) nums     -- [2,4,6,8]
filter even nums   -- [2,4]
take 2 nums        -- [1,2]
  • : prepends, ++ concatenates.
  • map, filter, take, and sum operate on lists.
  • head, tail, and (!!) are partial: they raise an error on the empty list (and (!!) on an out-of-range index). Prefer take, dropWhile, total pattern matching, or safeHead-style total functions over them in production code.

Pattern Matching

describe :: Int -> String
describe 1 = "one"
describe n | n < 0 = "negative"
           | otherwise = "other"

-- Lists
sumFirstTwice :: [Int] -> Int
sumFirstTwice (x : y : _) = x + y   -- ignores the rest
sumFirstTwice _            = 0      -- fewer than two elements
  • Function definitions can pattern-match on arguments.
  • Guards (| condition) refine matching; otherwise is a fallback.

Algebraic Data Types

data Color = Red | Green | Blue

-- `Maybe` already exists in Prelude; shown here only to illustrate the shape
data Maybe a = Nothing | Just a

data Shape
  = Circle Double
  | Rectangle Double Double

draw :: Color -> String
draw Red   = "red"
draw Green = "green"
draw Blue  = "blue"
  • data declares a new type; constructors begin with uppercase.
  • Maybe a models optional values (Nothing or Just a).
  • Fields in constructors can carry data (Circle Double).

Type Classes

-- A class constrains a type to support certain functions
class Pair a where
  multiply :: a -> a -> a

-- Instance for Int
instance Pair Int where
  multiply a b = a * b

-- Built-in common classes: Eq, Ord, Show, Read, Num
(==) :: Eq a => a -> a -> Bool
(<)  :: Ord a => a -> a -> Bool
show :: Show a => a -> String
  • A type class is an interface for functions that must exist for a type.
  • instance provides the implementation for a concrete type.
  • Eq, Ord, Show, and Read are standard classes.

Maybe and Either

-- Maybe-safe division
safeDiv :: Double -> Double -> Maybe Double
safeDiv _ 0 = Nothing
safeDiv a b = Just (a / b)

result :: Maybe Double
result = safeDiv 10 2     -- Just 5.0

divisible :: Double -> Double -> Either String Double
divisible _ 0 = Left "division by zero"
divisible a b = Right (a / b)

-- Pattern matching on the result
case safeDiv 10 0 of
  Nothing -> putStrLn "failed"
  Just v  -> print v
  • Maybe encodes optional values; Either String a can carry an error message.
  • Use pattern matching or case to consume them.

Standard Functions

-- Higher-order functions
foldr (+) 0 [1, 2, 3]     -- 6
foldl (+) 0 [1, 2, 3]     -- 6
zip [1, 2] ['a', 'b']     -- [(1,'a'),(2,'b')]

-- Partial application
plusTen :: Int -> Int
plusTen = (+) 10
plusTen 5                 -- 15

-- Composition and pipelines
result :: Int
result = (+ 1) . (* 2) $ 10   -- 21
  • foldr/foldl reduce a list using a binary function.
  • For processing long lists, prefer foldl' (strict) over foldl (lazy), which can build up deferred thunks and overflow the stack.
  • $ applies a function to its right argument with low precedence.

Monadic I/O

main :: IO ()
main = do
  putStrLn "Name?"
  name <- getLine
  putStrLn ("Hello, " ++ name ++ "!")
  • do blocks sequence actions in the IO monad.
  • <- binds the result of an action.
  • putStrLn and getLine are I/O actions.

References

Related Cheat Sheets