These are the Haskell operations and type classes we learned in FIT2102, collected here as a quick revision reference. Each table lists the operation, its type class or role, its meaning, and a simple example.

A method belongs to a type class. A helper uses that class’s operations but is not itself a method. Ordinary list and function operations are marked separately. IO is a type constructor, not a type class; it has Functor, Applicative, and Monad instances.

1. Mapping and applying functions

Operation Type class / role What it does Example → result
map List function Applies a function to every list element map (+3) [1,2] → [4,5]
fmap Functor method Maps over any Functor fmap (+3) (Just 2) → Just 5
<$> Functor helper Infix version of fmap: function on the left (+3) <$> Just 2 → Just 5
<&> Functor helper Flipped fmap: function on the right Just 2 <&> (+3) → Just 5
<$ Functor method Replaces mapped values with a fixed value 0 <$ [1,2,3] → [0,0,0]
pure Applicative method Introduces a value into an Applicative context pure 2 :: Maybe Int → Just 2
<*> Applicative method Applies a contextual function to a contextual value Just (+3) <*> Just 2 → Just 5
liftA2 Applicative method Applies a two-argument function to two contextual values liftA2 (+) (Just 2) (Just 3) → Just 5
<* Applicative method Sequences two computations, keeping the left result Just 2 <* Just 3 → Just 2
*> Applicative method Sequences two computations, keeping the right result Just 2 *> Just 3 → Just 3

These are equivalent:

1
2
3
4
5
fmap (+3) (Just 2)
(+3) <$> Just 2
Just 2 <&> (+3)
pure (+3) <*> Just 2
-- All produce Just 5

For multiple arguments:

1
2
(+) <$> Just 2 <*> Just 3
-- Just 5

For lists, <*> produces all combinations, rather than pairing elements by position:

1
2
[(+1), (*10)] <*> [1,2,3]
-- [2,3,4,10,20,30]

<* and *> keep the effects of both computations, including failure:

1
2
Just 2 <* Nothing -- Nothing
Nothing *> Just 3 -- Nothing

2. Alternatives and repetition

Operation Type class / role What it does Example → result
empty Alternative method Represents no result or failure empty :: Maybe Int → Nothing
<|> Alternative method Combines alternatives according to the instance Nothing <|> Just 3 → Just 3
asum Foldable + Alternative helper Combines a structure of alternatives using <|> and empty asum [Nothing, Just 2, Just 3] → Just 2
many Alternative method Repeats a computation zero or more times Parser examples below
some Alternative method Repeats a computation one or more times Parser examples below

<|> behaves differently for different types:

1
2
Just 2 <|> Just 3 -- Just 2
[1,2] <|> [3,4] -- [1,2,3,4]

Using our parser’s is operation:

1
2
3
4
5
6
7
8
parse (many (is 'a')) "aaab"
-- Just ("b", "aaa")

parse (many (is 'a')) "bbb"
-- Just ("bbb", "")

parse (some (is 'a')) "bbb"
-- Nothing

many allows zero matches; some requires at least one. A repeated parser must consume input when it succeeds.

These examples assume a parser result of Just (remainingInput, parsedValue). parse and is are operations defined by our parser, not standard type class methods; they require the parser definitions used in class.

3. Combining values: Semigroup and Monoid

Operation Type class / role What it does Example → result
<> Semigroup method Combines two values using their Semigroup operation "Hi" <> "!" → "Hi!"
mempty Monoid method Identity value for a Monoid mempty :: String → ""
mappend Monoid method Monoid combination, equivalent to <> mappend "Hi" "!" → "Hi!"
mconcat Monoid method Combines a list of Monoid values mconcat ["A","B","C"] → "ABC"
++ List function Specifically concatenates two lists [1,2] ++ [3] → [1,2,3]
concat Foldable helper Concatenates lists held in a Foldable structure concat [[1,2],[3]] → [1,2,3]

For lists, these happen to give the same result:

1
2
3
4
[1,2] ++  [3,4]
[1,2] <> [3,4]
[1,2] <|> [3,4]
-- All produce [1,2,3,4]

But <> is more general than list concatenation:

1
2
3
4
5
getSum (Sum 2 <> Sum 3)
-- 5

getProduct (Product 2 <> Product 3)
-- 6

Sum and Product choose how numbers combine. Their identities are Sum 0 and Product 1. A Semigroup operation must be associative; a Monoid also supplies an identity.

4. Folding and inspecting structures

Operation Type class / role What it does Example → result
foldr Foldable method Folds with right association; function receives element then accumulator foldr (-) 0 [1,2,3] → 2
foldl Foldable method Folds with left association; function receives accumulator then element foldl (-) 0 [1,2,3] → -6
fold Foldable method; Monoid elements Combines Monoid elements using <> and mempty fold ["A","B","C"] → "ABC"
foldMap Foldable method; Monoid result Maps elements to Monoid values, then combines them foldMap show [1,2,3] → "123"
sum Foldable method; Num elements Adds numeric elements sum [1,2,3] → 6
product Foldable method; Num elements Multiplies numeric elements product [2,3,4] → 24
length Foldable method Counts elements length (Just 5) → 1
null Foldable method Checks whether there are no elements null Nothing → True
elem Foldable method; Eq elements Checks membership elem "Ian" ["Ian","Bob"] → True
maximum Foldable method; Ord elements Returns the greatest element; requires nonempty input maximum [2,8,3] → 8
minimum Foldable method; Ord elements Returns the smallest element; requires nonempty input minimum [2,8,3] → 2
toList Foldable method Collects a Foldable’s elements into a list toList (Just 5) → [5]

The fold associations are:

1
2
3
4
5
6
7
foldr (-) 0 [1,2,3]
-- 1 - (2 - (3 - 0))
-- 2

foldl (-) 0 [1,2,3]
-- ((0 - 1) - 2) - 3
-- -6

Remember these relationships (written as equations):

1
2
3
4
fold xs = foldr (<>) mempty xs

-- For lists:
foldMap g xs = fold (map g xs)

For example:

1
2
getSum (foldMap Sum [1,2,3])
-- 6

5. Traversing and collecting effects

For these examples, define:

1
2
3
checkPositive :: Int -> Maybe Int
checkPositive x =
if x > 0 then Just x else Nothing
Operation Type class / role What it does Example → result
traverse Traversable method; Applicative effect Applies an effect-producing function and collects the effects traverse checkPositive [1,2] → Just [1,2]
sequenceA Traversable method; Applicative effect Collects effects already present in the structure sequenceA [Just 1, Just 2] → Just [1,2]

Compare:

1
2
3
4
5
6
7
8
map checkPositive [1,-2]
-- [Just 1, Nothing]

traverse checkPositive [1,-2]
-- Nothing

sequenceA [Just 1, Nothing]
-- Nothing

The distinction is:

1
2
map checkPositive      -- [Int] -> [Maybe Int]
traverse checkPositive -- [Int] -> Maybe [Int]

The relationship is:

1
2
3
4
sequenceA = traverse id

-- For lists:
traverse g xs = sequenceA (map g xs)

6. Monad operations

Operation Type class / role What it does Example → result
>>= Monad method Passes a computation’s result to a function returning the next computation Just 2 >>= (\x -> Just (x+3)) → Just 5
>> Monad method Sequences computations, discarding the first result Just 2 >> Just 3 → Just 3
return Monad method Same role as pure; it does not exit a function return 2 :: Maybe Int → Just 2

These two versions are equivalent:

1
2
3
4
5
6
7
8
9
10
Just 2 >>= (\x ->
Just 3 >>= (\y ->
pure (x + y)))

-- The same computation in do notation:
do
x <- Just 2
y <- Just 3
pure (x + y)
-- Just 5

do and <- are syntax, rather than ordinary functions. In these examples, they express the connections made with bind.

7. Useful ordinary function operations

Operation Type class / role What it does Example → result
$ Ordinary function Function application with low precedence sum $ map (+1) [1,2] → 5
. Ordinary function Function composition: right function first (show . (+1)) 2 → "3"
id Ordinary function Returns its input unchanged id 5 → 5
const Ordinary function Returns the first argument, ignoring the second const 5 "hello" → 5
flip Ordinary function Swaps a function’s first two arguments flip (-) 2 10 → 8
filter List function Keeps list elements satisfying a condition filter (>2) [1,2,3,4] → [3,4]
zipWith List function Combines corresponding elements of two lists zipWith (+) [1,2] [10,20] → [11,22]

8. IO: input and output

IO a describes an input/output action that produces a result of type a. Since IO has Functor, Applicative, and Monad instances, the same mapping, application, and bind operations work with IO actions.

Operation Type class / role What it does Simple example
getLine IO function: IO String Reads a line of input If we enter Ada, the action produces "Ada"
putStrLn IO function: String -> IO () Prints a string followed by a newline putStrLn "Hello" prints Hello
putStr IO function: String -> IO () Prints a string without adding a newline putStr "Hello" prints Hello
print IO helper; requires Show Converts a value using show and prints it with a newline print [1,2] prints [1,2]

For example:

1
2
3
4
5
main :: IO ()
main = do
putStrLn "What is your name?"
name <- getLine
putStrLn ("Hello, " ++ name)

Here, getLine is an IO String action, while name is the String made available to the following statements through bind.

Other familiar operations also work with IO:

1
2
3
4
5
6
7
8
length <$> getLine
-- Functor: reads a line and produces its length in IO.

(++) <$> getLine <*> getLine
-- Applicative: reads two lines and produces their concatenation in IO.

getLine >>= putStrLn
-- Monad: reads a line and then prints it.

Useful imports

1
2
3
4
5
import Control.Applicative
(empty, (<|>), liftA2, many, some)
import Data.Functor ((<&>))
import Data.Foldable (fold, toList, asum)
import Data.Monoid (Sum(..), Product(..))

The remaining standard operations shown above are available through Prelude. The parser examples additionally need our course parser definitions. Class labels here follow modern GHC’s base library.