-
Notifications
You must be signed in to change notification settings - Fork 4
0023 ‐ Email Tutorials Haskell For Beginners ‐ Algebraic Data Types with Haskell
Same video: Algebraic Data Types with Haskell
Earlier we defined:
newtype Day = Day Int
newtype Month = Month Int
newtype Year = Year IntNow imagine you load this into ghci and try:
ghci> d1You might see an error like:
No instance for (Show Day) …
What does this mean?
-
ghciis trying to print the value. - To print a value, Haskell uses the
Showtype class. - Our
Day,Month, andYeartypes don’t yet have aShowinstance. - So
ghcisays: “I don’t know how to show (print) aDay.”
We don’t fully understand type classes yet, so the course asks you to:
newtype Day = Day Int deriving Show
newtype Month = Month Int deriving Show
newtype Year = Year Int deriving ShowNow:
-
The
deriving Showclause tells the compiler:“Please auto-generate the code needed to convert this type to a
String.” -
After reloading in
ghci, printingd1,d2, etc. works.
You can think of deriving Show (for now) as:
“Make this type printable in
ghciand error messages.”
We’ll properly understand Show and type classes in a later module.
Now we build our own product type for dates using data.
Example:
data DateTC
= DateDC Int Int Int
deriving ShowBreakdown:
-
data– we are defining a new type. -
DateTC– the type constructor (the name of our type). -
=– definition. -
DateDC Int Int Int– a data constructor (or value constructor) that:- Takes three
Ints (day, month, year). - Constructs a value of type
DateTC.
- Takes three
-
deriving Show– auto-generateShowso we can print it inghci.
We can read it as:
“We define a custom type
DateTCwith one constructorDateDCthat stores threeInts.”
Using the “TC” and “DC” suffixes is just to make the teaching clearer:
data DateTC = DateDC Int Int Int
deriving Show-
Type constructor:
DateTC- Used in type signatures.
-
Data constructor:
DateDC- Used to build actual values.
Example values:
d2 :: DateTC
d2 = DateDC 1 1 2025
d3 :: DateTC
d3 = DateDC 31 12 1999- In the type signature, we use
DateTC. - In the value definition, we call
DateDClike a function.
Ask ghci for the type of the data constructor:
ghci> :t DateDC
DateDC :: Int -> Int -> Int -> DateTCSo DateDC:
- Takes 3
Intarguments. - Returns a
DateTC.
This means data constructors behave like functions:
DateDC 1 1 2025 -- applying a “function” of 3 IntsNow, what about this more idiomatic declaration?
data Date = Date Int Int Int
deriving ShowThen:
-
Date(in a type signature) refers to the type. -
Date(in a value) refers to the data constructor / function.
Example:
today :: Date
today = Date 1 1 2025ghci:
ghci> :t Date
Date :: Int -> Int -> Int -> Date- The first
Date(that we ask:tabout) is the data constructor. - The second
Date(in the type) is the type constructor. - After
::only types appear, so thatDatemust be the type.
If you ask for the type of the type constructor directly (in a polymorphic sense), you’ll get an error here, because :t is for values/functions, not for “types of types”. We’ll revisit this when we talk about polymorphic types and kinds.
Compare:
-- Raw triple of Ints
date1 :: (Int, Int, Int)
-- Custom type
date2 :: DateWith our custom type:
- The type signatures clearly state “this is a
Date”. - It’s easier to understand and maintain.
But we’re still using raw Ints inside:
badDate :: Date
badDate = Date 31 31 2025 -- invalid month, but type-checksSo:
- We gained readability, but not full validity guarantees yet.
- Later, we’ll refine the internal types (
Day,Month,Yearwithnewtypeor smart constructors) to prevent invalid dates.
We’ve seen product types (combinations of values). Now we look at sum types (choices between alternatives).
The Bool type is defined like this:
data Bool = True | False-
data– we’re defining a type. -
Bool– the type constructor / type name. -
=– definition. -
True | False– two data constructors, separated by|(read as “or”).
Read aloud:
“
Boolis a type that can beTrueorFalse.”
Key points:
-
The
|(pipe) in adatadeclaration means “or” between constructors. -
Boolis a sum type:- It has 2 constructors.
- So it has exactly 2 possible values.
-
In general:
- Sum type: number of values = sum of values of each alternative.
- Product type: number of values = product of values of each component.
We’ll see more complex sum types (with constructors that take arguments) later, but Bool is the simplest possible example.
-
Product type: A type that combines several components (like tuples or our
Date), where the number of possible values is the product of the possibilities of each component. -
Sum type: A type that represents a choice between alternatives (like
Bool), where the number of possible values is the sum of the alternatives’ possibilities. -
Type constructor: The name of the type itself (e.g.
Date,Bool), used in type signatures. -
Data constructor / Value constructor: The “function” that builds values of the type (e.g.
Date 1 1 2025,True,False). -
deriving Show: An instruction to the compiler to auto-generate printing code so values can be converted toString(used byghciand error messages).
A. It automatically validates that the data is always correct.
B. It tells the compiler how to convert values of the type to String, so they can be printed.
C. It makes the type faster at runtime.
D. It turns the type into a sum type.
Answer: B
A. Only a type constructor.
B. Only a data constructor.
C. Both a type constructor and a data constructor, depending on context.
D. Neither – Date is just a synonym.
Answer: C
A. Date
B. Int -> Date
C. Int -> Int -> Int -> Date
D. (Int, Int, Int) -> Date
Answer: C
A. Because it stores the sum of two Ints.
B. Because its values are formed from the Cartesian product of two sets.
C. Because it has two alternatives (True and False), and the total number of values is the sum of the alternatives.
D. Because it uses addition operators internally.
Answer: C
A. It separates arguments to a constructor. B. It means “and”, both constructors must hold at once. C. It means “or”: the type can be constructed by any one of the alternatives. D. It means division.
Answer: C
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: