-
Notifications
You must be signed in to change notification settings - Fork 4
3. Haskell Symbols Semigroup, Monoid, Functor, Applicative and Monad Operators
- Introduction
-
Semigroup
- 2.1 Mathematical Background
- 2.2 Semigroup in Haskell
- 2.3 Examples and Instances
-
Monoid
- 3.1 Mathematical Background
- 3.2 Monoid in Haskell
- 3.3 Examples and Instances
- Type Variables vs Concrete Types
- Operator
(<>) - Functor and
<$> - Applicative and
<*> - Monad:
>>=(bind) and>>(then) - Comparison Table of Operators
- Glossary of Terms
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.
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.
Typeclass:
class Semigroup a where
(<>) :: a -> a -> a-
ais a type variable — can be any type that implements `<>'. - Must satisfy associativity law.
-- Lists
[1,2] <> [3,4] -- [1,2,3,4]
-- Strings
"foo" <> "bar" -- "foobar"
-- Sum
import Data.Monoid
Sum 3 <> Sum 7 -- Sum 10A monoid is:
- A semigroup
- With an identity element
mempty - That satisfies:
- Left identity:
mempty <> x = x - Right identity:
x <> mempty = x
- Left identity:
Typeclass:
class Semigroup a => Monoid a where
mempty :: a
mconcat :: [a] -> a-- Lists
mempty :: [a] -- []
mconcat [[1],[2],[3]] -- [1,2,3]
-- Sum and Product
mempty :: Sum Int -- Sum 0
mempty :: Product Int -- Product 1-
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-
ais a type variable. - In:
instance Semigroup Int where ...a becomes the concrete type Int.
-
Typeclass:
Semigroup - Pronounced: append (most common), sometimes mappend or diamond
- Meaning: Combine two values.
-
Example:
"foo" <> "bar" -- "foobar" Sum 2 <> Sum 3 -- Sum 5
-
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
-
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]
- 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
- 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"
| 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 |
- 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
IntorString. -
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.
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.
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: B — a is a type variable meaning “any type that implements Semigroup”.
A. 0
B. 1
C. []
D. Nothing
Answer: A — The identity element for Sum is Sum 0.
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.
Just (+1) <*> Just 5What 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.
A. <*>
B. <$>
C. >>=
D. >>
Answer: C — >>= is bind.
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.
A. Associativity B. Left identity C. Commutativity D. Right identity Answer: C — Monoids don’t require commutativity.
A. \x -> x (the identity function)
B. \x -> x + 1
C. 0
D. Nothing
Answer: A — For Endo a, mempty is the identity function.
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.
import Data.Monoid
Sum 2 <> Sum 5What is the result?
A. Sum 7
B. Sum 10
C. 7
D. Compilation error
Answer: A — Sum uses addition: 2 + 5 = 7.
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.
(+1) <$> Just 5What is the result?
A. Just 6
B. Just 5
C. Nothing
D. Compilation error
Answer: A — <$> maps the function (+1) over the Just value.
Just (+1) <*> Just 10What 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.
[(*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].
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.
Nothing >>= \x -> Just (x + 1)What is the result?
A. Nothing
B. Just 1
C. Compilation error
D. 0
Answer: A — Nothing short-circuits the bind operation.
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.
mappend (Product 3) (Product 4)What is the result?
A. Product 12
B. Product 7
C. 12
D. Compilation error
Answer: A — Product uses multiplication: 3 × 4 = 12.
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.
Bernard Sibanda is a global Technology Entrepreneur, Web3 and Software Consultant with a deep focus on Cardano Blockchain, Midnight and Community building.
Key Positions:
- Founder, CTO, Developer Advocate cohort #1, Fullstake Developer, Cardano Ambassador, Catalyst Project Manager, DREP-WIMS:
- Co-founder of ABL Tech and Cardano Africa Live
- EBU-certified Plutus Pioneer (Plutus/Haskell)
- Cohort #1 Plutus Pioneer Developer
- Catalyst Community Reviewer & Funded Projects Manager
-
DRep for WIMS-Cardano (ID:
drep1yguj8zu48n99pv70yl6ckzt9hdgjy8yjnlqs2uyzcpafnjgu4vkul) - Intersect Developer Advocate
- Intersect Committe Member 2025-2026
- Cardano Marketer,Promoter and blogger
- Cardano Open Source Contributor
- Cardano communities and events organizer and builder
- Cardano Ambassador for South Africa
Official links:
- Stablecoins Dex
- Coxygen Global Universities
- WIMS Cardano Global
- Cardano Africa Live
- WIMS Cardano Videos
- Cardano Smart Contract Videos
- Fullstack IT Consulting
Social links: