Thinking with Types Type level Programming in Haskell Sandy Maguire all chapter instant download
Thinking with Types Type level Programming in Haskell Sandy Maguire all chapter instant download
com
https://textbookfull.com/product/thinking-with-types-type-
level-programming-in-haskell-sandy-maguire/
OR CLICK BUTTON
DOWNLOAD NOW
https://textbookfull.com/product/thinking-functionally-with-haskell-
richard-bird/
textboxfull.com
https://textbookfull.com/product/programming-in-haskell-2nd-edition-
graham-hutton/
textboxfull.com
https://textbookfull.com/product/programming-in-haskell-second-
edition-5th-printing-edition-hutton/
textboxfull.com
https://textbookfull.com/product/algebra-driven-design-elegant-
software-from-simple-building-blocks-version-1-1-2-sandy-maguire/
textboxfull.com
Thinking Low Level Writing High Level 2nd Edition Randall
Hyde
https://textbookfull.com/product/thinking-low-level-writing-high-
level-2nd-edition-randall-hyde/
textboxfull.com
https://textbookfull.com/product/haskell-the-ultimate-beginner-s-
guide-to-learn-haskell-programming-step-by-step-1st-edition-claudia-
alves/
textboxfull.com
https://textbookfull.com/product/the-haskell-road-to-logic-maths-and-
programming-kees-doets/
textboxfull.com
https://textbookfull.com/product/algorithm-design-with-haskell-
richard-s-bird/
textboxfull.com
Sandy
Sandy Maguire
Maguire
Copy
Copyrig
right
ht ©201
©2018,
8, Sand
Sandyy Magu
Maguire
ire
First
First Edition
Edition
When people say
“but most business logic bugs
aren’t type errors,”
I just want to show them
how to make bugs
into type errors.
MATT PARSONS
Contents
Preface ix
Acknowledgments xi
Introduction 1
I Fundamentals 5
1 The Algebra Behind Types 7
1.1 Isomorphisms and Cardinalities . . . . . . . . . . . . . . . 7
1.2 Sum, Product and Exponential Types . . . . . . . . . . . . 10
1.3 Example: Tic-Tac-Toe . . . . . . . . . . . . . . . . . . . . . 13
1.4 The Curry–Howard Isomorphism . . . . . . . . . . . . . . 15
1.5 Canonical Representations . . . . . . . . . . . . . . . . . . 16
2 Terms, Types and Kinds 19
2.1 The Kind System . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.1.1 The Kind of “Types” . . . . . . . . . . . . . . . . . . 20
2.1.2 Arrow Kinds . . . . . . . . . . . . . . . . . . . . . . . 20
2.1.3 Constraint Kinds . . . . . . . . . . . . . . . . . . . . 21
2.2 Data Kinds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3 Promotion of Built-In Types . . . . . . . . . . . . . . . . . 25
2.3.1 Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3.2 Natural Numbers . . . . . . . . . . . . . . . . . . . . 27
2.3.3 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.3.4 Tuples . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.4 Type-Level Functions . . . . . . . . . . . . . . . . . . . . . 30
3 Variance 35
v
vi CONTENTS
II Lifting Restrictions 41
4 Working with Types 43
4.1 Type Scoping . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.2 Type Applications . . . . . . . . . . . . . . . . . . . . . . . . 45
4.3 Ambiguous Types and Non-Injectivity . . . . . . . . . . . 47
5 Constraints and GADTs 51
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.2 GADTs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.3 Heterogeneous Lists . . . . . . . . . . . . . . . . . . . . . . 55
6 Rank-N Types 61
6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.2 Ranks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
6.3 The Nitty Gritty Details . . . . . . . . . . . . . . . . . . . . . 65
6.4 The Continuation Monad . . . . . . . . . . . . . . . . . . . 66
7 Existential Types 71
7.1 Existential Types and Eliminators . . . . . . . . . . . . . . 71
7.1.1 Dynamic Types . . . . . . . . . . . . . . . . . . . . . 74
7.1.2 Generalized Constraint Kinded Existentials . . . . 76
7.2 Scoping Information with Existentials . . . . . . . . . . . 79
8 Roles 85
8.1 Coercions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
8.2 Roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
IV Appendices 203
Glossary 205
Solutions 211
Bibliography 233
About the Author 235
viii CONTENTS
Preface
Thinking with Types started, as so many of my projects do,
accidentally. I was unemployed, bored, and starting to get tired of
answering the same questions over and over again in Haskell
chat-rooms. And so I started a quick document, jotting down a
bunch of type-level programming topics I thought it’d be fun to
write blog posts about.
This document rather quickly turned into an outline of what those
blog posts might look like, but as I was about to tease it apart into
separate files I stopped myself. Why not turn it into a book instead?
I approached some friends to see if anyone was interested in
writing it with me. A few nibbles, but nobody had time they wanted
to dedicate to such a thing. My excitement subsequently burned out,
and the idea lay dormant on the back-burner for a few months.
But I was still unemployed, and I was still bored, and I found
myself slowly fleshing out chapters regardless. My enthusiasm for
writing a book had died down, but I still felt the urge to write. A
friend caught me writing one day, and dared me to publish what I
had. I acquiesced.
And so on July 8th, 2018, I posted a 37 page document to reddit,
gauging if there was any interest from the community in such a book.
To my continual surprise, there was. The response was about 100x
bigger than I was expecting. Kind words and letters of support rolled
in, many of whom promised to pay me in order to continue writing
it.
That was enough for me. I put together a Patreon, started selling
early access to the book, and was o to the races. The promise was
to publish weekly updates, which—combined with not wanting to
commit fraud—kept me extremely motivated to get this book
finished. It’s a powerful technique to stay focused, and I’d strongly
ix
x CONTENTS
xi
xii CONTENTS
Introduction
Type-level programming is an uncommon calling. While most
programmers are concerned with getting more of their code to
compile, we type-level programmers are trying our best to prevent
code from compiling.
Strictly speaking, the job of types is twinfold—they prevent
(wrong) things from compiling, and in doing so, they help guide us
towards more elegant solutions. For example, if there are ten
solutions to a problem, and nine of them be poorly-typed, then we
need not look very hard for the right answer.
But make no mistake—this book is primarily about reducing the
circumstances under which a program compiles. If you’re a beginner
Haskell programmer who feels like GHC argues with you too often,
who often finds type errors inscrutable, then this book is probably
not for you. Not yet.
So whom is this book for? The target audience I’ve been trying to
write for are intermediate-to-proficient with the language. They’re
capable of solving real problems in Haskell, and doing it without too
much hassle. They need not have strong opinions on ExceptT vs
throwing exceptions in IO , nor do they need to know how to inspect
generated Core to find performance bottlenecks.
But the target reader should have a healthy sense of unease
about the programs they write. They should look at their comments
saying “don’t call this function with n = 5 because it will crash,”
and wonder if there’s some way to teach the compiler about that.
The reader should nervously eyeball their calls to error that they’re
convinced can’t possibly happen, but are required to make the
type-checker happy.
In short, the reader should be looking for opportunities to make
less code compile. This is not out of a sense of masochism, anarchy,
1
2 CONTENTS
Fundamentals
5
Chapter 1
1.1
1.1 Is
Isom
omor
orph
phis
isms
ms and
and Ca
Card
rdin
inal
alit
itie
iess
One of functio
functional
nal program
programmin ming’s
g’s killer
killer featur
features
es is pattern
pattern matchin
matching,g,
as made possible by algebraic data types . But this this term
term isn’t
isn’t just
just a
catchy title for things that we can pattern match on. As their name
sugge
uggessts,
ts, ther
theree is in fact
fact an algebra behind algebraic data types.
Being comfortable understanding and manipulating this algebra
is a mighty superpower—it allows us to analyze types, find more
convenient forms for them, and determine which operations (eg.
type
typecla
class
sses
es)) are
are poss
possibl
iblee to imple
impleme
ment nt..
To start, we can associate each type with its cardinality—the
numb
number er of inha
inhabit
bitan
ants
ts it has,
has, ignori
ignoring ng bottom
bottoms.s. Cons
Consid
ider
er the
followi
following
ng simple
simple type definiti
definitionsons::
data Void
data () = ()
7
8 CHAPTER
CHAPTER 1. THE ALGEBRA
ALGEBRA BEHIND TYPES
|Void| = 0
|()| = 1
|Bool| = 2
Any two types that have the same cardinality will always be
isomorphic
isomorphic to one another. An isomorphism between types s and t is
defin
de fined
ed as a pair
pair of fun
functio
ction
ns to and from:
to :: s -> t
from :: t -> s
such that composing either after the other gets you back where
you started. In other words, such that:
to . from = id
from . to = id
By the
the argu
argume
ment nt abov
above,
e, we shou
should
ld expe
expect
ct Spin to be isom
isomor
orph
phic
ic to
Bool. Ind
Indee
eedd it is:
is:
1.2
1.2 Sum,
Sum, Pr
Prod
oduc
uctt and
and Ex
Exp
ponen
onenti
tial
al Type
Typess
In the language of cardinalities, sum types correspond to addition.
The
The cano
canoni
nica
call exam
examplplee of thes
thesee is Eith er a b, which is either an a or a
Either
b. As a resul
result,
t, the
the cardi
cardina
nalit
lityy (reme
(rememb mber,
er, the
the numb
number
er of inha
inhabit
bitan
ants
ts))
of Eith er a b is the
Either the card
cardininal
alit
ityy of a plus
plus the
the card
cardin
inal
alit
ityy of b .
As you might expect, this is why such things are called sum types.
The intu
intuiti
ition
on behin
behind d addi
adding
ng gene
genera
raliz
lizes
es to any
any data
dataty
type
pe with
with
multiple constructors—the cardinality of a type is always the sum
of the
the card
cardin
inal
aliti
ities
es of its
its const
constru
ructo
ctors
rs..
data Deal a b
= This a
| That b
| TheO
TheOther
ther Bool
Maybe a| = 1 + |a|
|Maybe
Dual to sum types are the so-called product types. Again, we will
loo
look at thethe canonica ical example first—tht—thee pair type
type (a,
(a, b).
Analogously, the
t he cardinality of a product type is the product of their
cardinalities.
|(a,
(a, b)| = |a| × |b|
prodUnitFrom :: (a, ()
())
) -> a
prodUnitFrom (a, ()
())
) = a
The function absurd at 1 has the type Voi Voidd -> a. It’s
It’s a sort
sort of
of
blu saying “if you give me a Void I can can give
give you
you anyt
anythi
hing
ng you
you want
want.”.”
Despite this being a lie, because there are no Voids to be had in the
first
first plac
place,
e, we can’
can’tt disp
dispro
rove
ve it.
it.
Func
Functio
tion
n type
typess also
also have
have an encod encodining
g as stat
stateme
ementntss abou
aboutt
cardina
cardinality
lity—th
—they ey correspo
correspondnd to exponentia
exponentializa lization
tion.. To give an
example, there are exactly four (2 ) inhabitants of the type Boo
2
Bool
l ->
Bool. These functions are id, not, const True and const
const True False. Try as
const False
hard
hard as you
you can,
can, but
but you
you won’
won’tt findfind anyany othe
otherr pure
pure func
functi
tion
onss
between Bools!
More generally, the type a -> - > b has cardinality |b||a| . While
While this
this
migh
mightt be surp
surpri
risi
sing
ng at first
first—i
—itt alwa
alwaysys seem
seemss back
backwaward
rdss to me—t
me—the he
argument is straightforward. For every value of a in the domain, we
need to give back a b. But we can can cho
chose any valvalue of b for
for ever
everyy valu
valuee
of a —res
—resul
ulti
ting
ng in the
the follo
followin
wingg equa
equalitlity.
y.
Exerci
Exercise
se 1.2-i
1.2-i
Determine the cardinality of Eit
Eithe
her
r Bool
Bool (Bool
(Bool,
, Maybe
Maybe Bool
Bool)
) ->
Bool.
The
The inqu
inquisisiti
itive
ve read
reader
er might
might wonde
wonderr wheth
whetherer subtr
subtrac
actio
tion,
n,
division and other mathematical operations have meaning when
applied
applied to types.
types. Indeed
Indeed they do, but such things
things are hard,
hard, if not
impossible,
impossible, to express in Haskell. Subtraction
Subtraction corresponds
corresponds to types
with particular values removed, while division of a type makes some
of its values equal (in the sense of being defined equally—rather
than
than havi
having
ng an Eq inst
instan
ance
ce which
which equa
equatetess them.
them.))
In fact
fact,, even
even thethe noti
notion
on of die
diere
rent
ntia
iati
tion
on in calc
calcul
ulus
us has
has
mean
meaniningg in the domain
domain of types
types.. Thou
Thoughgh we wiwill
ll not discus
discusss it
furt
furthe
her,
r, the
the inte
interes
reste
ted
d read
reader
er is enco
encoururag
aged
ed to refer
refer to Cono
Conorr
McBride’s paper “The Derivative of a Regular Type is its Type of
One-Hole
One-Hole Contexts.”[8
Contexts.”[8]. ].
1.3. EXAMPLE: TIC-TAC-TOE 13
1.3
1.3 Ex
Exam
ampl
ple:
e: Tic-T
Tic-Tac-
ac-To
Toee
I said earlier that being able to manipulate the algebra behind types
is a migh
mighty ty supe
superp
rpow
ower
er.. Le
Let’
t’ss prov
provee it.
it.
Imagine
Imagine we wanted to write a game of tic-tac-toe.
tic-tac-toe. The standard
standard
tic-tac-toeboardhasninespaces,whichwecouldnaivelyimplement
like
like this
this::
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
textbookfull.com