diff --git a/examples/refinement.html.pm b/examples/refinement.html.pm
new file mode 100644
index 0000000..8c32ab7
--- /dev/null
+++ b/examples/refinement.html.pm
@@ -0,0 +1,11 @@
+#lang pollen
+
+◊p{
+ As students learn to work with invariants, it is helpful and
+ instructive to express them directly in the source program. Pyret
+ supports ◊em{refinments} to enable this. Currently, refinements in
+ Pyret are checked dynamically, so that students don't have to go
+ through the hurdles of convincing a proof-assistant that the
+ program is compliant, and they can get concrete examples of
+ failures.
+ }
diff --git a/examples/refinement.js b/examples/refinement.js
new file mode 100644
index 0000000..57d384b
--- /dev/null
+++ b/examples/refinement.js
@@ -0,0 +1,44 @@
+const example = `use context starter2024
+
+fun is-sorted-ascending(l :: List) -> Boolean:
+ cases (List) l:
+ | empty => true
+ | link(f, r) =>
+ cases (List) r:
+ | empty => true
+ | link(fr, rr) =>
+ if f <= fr:
+ is-sorted-ascending(r)
+ else:
+ false
+ end
+ end
+ end
+end
+
+fun insert(n :: Number,
+ l :: List%(is-sorted-ascending))
+ -> List%(is-sorted-ascending):
+ cases (List) l:
+ | empty => [list: n]
+ | link(f, r) =>
+ if n < f: link(n, l)
+ else: link(f, insert(n, r))
+ end
+ end
+end
+
+check:
+ insert(1, [list: 2, 3, 4]) is [list: 1, 2, 3, 4]
+ insert(1, [list: 3, 2, 4]) raises "predicate"
+end
+
+# Uncomment and run the next line to see the error message!
+# insert(1, [list: 3, 2, 4])
+`;
+
+export const refinement = {
+ definitionsAtLastRun: example,
+ editorContents: example,
+ replContents: ""
+};
diff --git a/index.html.pm b/index.html.pm
index 701a555..4b209c2 100644
--- a/index.html.pm
+++ b/index.html.pm
@@ -14,6 +14,7 @@
("tables" . "Tables")
("data" . "Data Structures")
("lambdas" . "Lambdas")
+ ("refinement" . "Type Refinements")
("oop" . "Object-Oriented Programming")
("forloops" . "Loops")
("mutation" . "Mutation and State")