Skip to content

3. Haskell Symbols Semigroup, Monoid, Functor, Applicative and Monad Operators

Bernard Sibanda edited this page Aug 9, 2025 · 1 revision

📑 Table of Contents

  1. Introduction
  2. Semigroup
    • 2.1 Mathematical Background
    • 2.2 Semigroup in Haskell
    • 2.3 Examples and Instances
  3. Monoid
    • 3.1 Mathematical Background
    • 3.2 Monoid in Haskell
    • 3.3 Examples and Instances
  4. Type Variables vs Concrete Types
  5. Operator (<>)
  6. Functor and <$>
  7. Applicative and <*>
  8. Monad: >>= (bind) and >> (then)
  9. Comparison Table of Operators
  10. Glossary of Terms

1. Introduction

Haskell uses typeclasses to describe abstract behaviors that many types can share. Some of the most fundamental are Semigroup, Monoid, Functor, Applicative, and Monad. They let you write generic code that works across numbers, strings, lists, functions, IO actions, and more.

2. Semigroup

2.1 Mathematical Background

A semigroup is:

  • A set S
  • With a binary operation <> : S × S → S
  • That satisfies associativity: $$ (x <> y) <> z = x <> (y <> z) $$ Example: Integers under addition.

2.2 Semigroup in Haskell

Typeclass:

class Semigroup a where
  (<>) :: a -> a -> a
  • a is a type variable — can be any type that implements `<>'.
  • Must satisfy associativity law.

2.3 Examples and Instances

-- Lists
[1,2] <> [3,4]   -- [1,2,3,4]
-- Strings
"foo" <> "bar"   -- "foobar"
-- Sum
import Data.Monoid
Sum 3 <> Sum 7   -- Sum 10

3. Monoid

3.1 Mathematical Background

A monoid is:

  • A semigroup
  • With an identity element mempty
  • That satisfies:
    • Left identity: mempty <> x = x
    • Right identity: x <> mempty = x

3.2 Monoid in Haskell

Typeclass:

class Semigroup a => Monoid a where
  mempty  :: a
  mconcat :: [a] -> a

3.3 Examples and Instances

-- Lists
mempty :: [a]   -- []
mconcat [[1],[2],[3]]   -- [1,2,3]
-- Sum and Product
mempty :: Sum Int      -- Sum 0
mempty :: Product Int  -- Product 1

4. Type Variables vs Concrete Types

  • Type variable: Placeholder for any type. Lowercase names: a, b.
    id :: a -> a
  • Concrete type: Fixed type like Int, Bool, [Char].
    addInt :: Int -> Int -> Int

When we write:

class Semigroup a where
  • a is a type variable.
  • In:
instance Semigroup Int where ...

a becomes the concrete type Int.

5. Operator (<>)

  • Typeclass: Semigroup
  • Pronounced: append (most common), sometimes mappend or diamond
  • Meaning: Combine two values.
  • Example:
    "foo" <> "bar"    -- "foobar"
    Sum 2 <> Sum 3    -- Sum 5

6. Functor and <$>

  • Typeclass: Functor
  • Pronounced: fmap
  • Type signature:
    (<$>) :: Functor f => (a -> b) -> f a -> f b
  • Meaning: Apply a function to a value inside a context.
  • Example:
    (+1) <$> [1,2,3]     -- [2,3,4]
    length <$> Just "hi" -- Just 2

7. Applicative and <*>

  • Typeclass: Applicative
  • Pronounced: ap or apply
  • Type signature:
    (<*>) :: Applicative f => f (a -> b) -> f a -> f b
  • Meaning: Apply a function inside a context to a value inside a context.
  • Example:
    Just (+1) <*> Just 5       -- Just 6
    [(+1), (*2)] <*> [10,20]   -- [11,21,20,40]

8. Monad: >>= (bind) and >> (then)

8.1 >>= — bind

  • Pronounced: bind
  • Type signature:
    (>>=) :: Monad m => m a -> (a -> m b) -> m b
  • Meaning: Take a monadic value, feed its unwrapped value to a function that returns a monad, and flatten the result.
  • Example:
    Just 3 >>= (\x -> Just (x + 1))  -- Just 4

8.2 >> — then

  • Pronounced: then
  • Type signature:
    (>>) :: Monad m => m a -> m b -> m b
  • Meaning: Do the first action, ignore its result, then do the second.
  • Example:
    putStrLn "Hello" >> putStrLn "World"

9. Comparison Table of Operators

Operator Typeclass Pronounced Purpose
<>) Semigroup append Combine two values
<$> Functor fmap Apply a function to wrapped value
<*> Applicative ap / apply Apply wrapped function to wrapped value
>>= Monad bind Pass result into function returning monad
>> Monad then Sequence actions, ignore first result

10. Glossary of Terms

  • Typeclass: A set of types that implement the same operations (like an interface in OOP).
  • Type variable: A generic placeholder for any type (a, b…).
  • Concrete type: A fixed, specific type like Int or String.
  • Semigroup: Type with associative binary operation (<>).
  • Monoid: Semigroup with an identity element (mempty).
  • Functor: Type that can be mapped over (fmap / <$>).
  • Applicative: Functor that supports function application inside a context (<*>).
  • Monad: Applicative with bind (>>=) for sequencing computations that may depend on previous results.
  • Endofunction: Function from a type to the same type (a -> a).
  • Context: The “wrapper” around a value — could be a list, Maybe, IO, etc. Alright — I’ll extend the tutorial with Section 11: Multiple Choice Questions so you can test yourself. I’ll mix beginner-friendly and trickier questions to check both syntax and concepts.

11. Multiple Choice Questions (MCQs)

Q1. Which statement about Semigroup is correct?

A. It must have an identity element. B. Its operation must be associative. C. Its operation must be commutative. D. It can only be defined for numeric types. Answer: B — Associativity is required; identity is only required for Monoid, and commutativity is not required.

Q2. In Haskell, what does the type variable a in

class Semigroup a where ...

represent? A. A specific type like Int B. Any type that can have a Semigroup instance C. Only numeric types D. Only list types Answer: Ba is a type variable meaning “any type that implements Semigroup”.

Q3. What is the identity element for Sum Int in Haskell?

A. 0 B. 1 C. [] D. Nothing Answer: A — The identity element for Sum is Sum 0.

Q4. What does <$> do?

A. Combines two values B. Maps a function over a wrapped value C. Applies a wrapped function to a wrapped value D. Sequences two monadic actions ignoring the first result Answer: B<$> is infix fmap.

Q5. Given:

Just (+1) <*> Just 5

What is the result? A. Just (+1, 5) B. Just 6 C. Nothing D. Compilation error Answer: B<*> applies a wrapped function to a wrapped value.

Q6. Which operator is called bind?

A. <*> B. <$> C. >>= D. >> Answer: C>>= is bind.

Q7. What does >> do?

A. Combines two values using Semigroup B. Maps a function over a Functor C. Runs two monadic actions, ignoring the first result D. Applies a function inside an Applicative to a value inside an Applicative Answer: C>> sequences monadic actions, discarding the first result.

Q8. Which of these is NOT a law of Monoid?

A. Associativity B. Left identity C. Commutativity D. Right identity Answer: C — Monoids don’t require commutativity.

Q9. In Endo Int, what does mempty represent?

A. \x -> x (the identity function) B. \x -> x + 1 C. 0 D. Nothing Answer: A — For Endo a, mempty is the identity function.

Q10. Which is the most accurate analogy?

A. <$> = “put a function in a box” B. <*> = “apply a function in a box to a value in a box” C. >>= = “apply a function to two values” D. <> = “unwrap a value from a box” Answer: B<*> applies a wrapped function to a wrapped value.

Q11.

import Data.Monoid
Sum 2 <> Sum 5

What is the result? A. Sum 7 B. Sum 10 C. 7 D. Compilation error Answer: ASum uses addition: 2 + 5 = 7.

Q12.

import Data.Semigroup
"foo" <> "bar" <> "baz"

What is the result? A. "foobar" B. "barfoobaz" C. "foobarbaz" D. "bazbarfoo" Answer: C — String concatenation is associative left-to-right here.

Q13.

(+1) <$> Just 5

What is the result? A. Just 6 B. Just 5 C. Nothing D. Compilation error Answer: A<$> maps the function (+1) over the Just value.

Q14.

Just (+1) <*> Just 10

What is the result? A. Just 11 B. Just (+1, 10) C. Nothing D. Compilation error Answer: A<*> applies the wrapped (+1) to the wrapped 10.

Q15.

[(*2), (+3)] <*> [1, 2]

What is the result? A. [2, 4, 4, 5] B. [2, 4, 5, 6] C. [2, 3, 4, 5] D. [2, 4, 5, 7] Answer: B — Applicative list instance applies each function to each element: (*2)[2, 4] (+3)[4, 5] Combined: [2, 4, 4, 5].

Q16.

Just 5 >>= \x -> Just (x * 2)

What is the result? A. Just 5 B. Just 10 C. Nothing D. Compilation error Answer: B>>= feeds 5 into the lambda, doubling it.

Q17.

Nothing >>= \x -> Just (x + 1)

What is the result? A. Nothing B. Just 1 C. Compilation error D. 0 Answer: ANothing short-circuits the bind operation.

Q18.

putStrLn "A" >> putStrLn "B"

What happens? A. Prints “A” and “B” on separate lines B. Prints “B” then “A” C. Compilation error D. Prints nothing Answer: A>> sequences actions, ignoring the first result.

Q19.

mappend (Product 3) (Product 4)

What is the result? A. Product 12 B. Product 7 C. 12 D. Compilation error Answer: AProduct uses multiplication: 3 × 4 = 12.

Q20.

import Data.Monoid
(appEndo (Endo (+1) <> Endo (*2)) 3)

What is the result? A. 8 B. 7 C. 5 D. Compilation error Answer: B(<>) for Endo composes functions: (x+1) . (x*2) applied to 3 gives (3*2)+1 = 7.

Clone this wiki locally