diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+1.36.0
+
+* [Supports version 19.0.0 of the standard](https://github.com/dhall-lang/dhall-lang/releases/tag/v19.0.0)
+    * BREAKING CHANGE TO THE API: [Add `Text/replace` built-in](https://github.com/dhall-lang/dhall-haskell/pull/2063)
+    * [Implement `with` without syntactic sugar](https://github.com/dhall-lang/dhall-haskell/pull/2055)
+* [`dhall lint` will now add a `.dhall` extension to all Prelude imports](https://github.com/dhall-lang/dhall-haskell/pull/2061)
+    * The old extension-free Prelude imports are deprecated
+* [Fix command-line completions for files](https://github.com/dhall-lang/dhall-haskell/pull/2016)
+* [Improve Template Haskell support for record constructors](https://github.com/dhall-lang/dhall-haskell/pull/2070)
+* Fixes and improvements to code formatting
+    * [#2037](https://github.com/dhall-lang/dhall-haskell/pull/2037)
+    * [#2048](https://github.com/dhall-lang/dhall-haskell/pull/2048)
+    * [#2069](https://github.com/dhall-lang/dhall-haskell/pull/2069)
+
 1.35.0
 
 * [Supports version 18.0.0 of the standard](https://github.com/dhall-lang/dhall-lang/releases/tag/v18.0.0)
diff --git a/dhall-lang/Prelude/Bool/package.dhall b/dhall-lang/Prelude/Bool/package.dhall
--- a/dhall-lang/Prelude/Bool/package.dhall
+++ b/dhall-lang/Prelude/Bool/package.dhall
@@ -1,25 +1,25 @@
 { and =
-      ./and sha256:0b2114fa33cd76652e4360f012bc082718944fe4c5b28c975483178f8d9b0a6d
-    ? ./and
+      ./and.dhall sha256:0b2114fa33cd76652e4360f012bc082718944fe4c5b28c975483178f8d9b0a6d
+    ? ./and.dhall
 , build =
-      ./build sha256:add7cb9acacac705410088d876a7e4488e046a7aded304f06c51accffd7f1b7b
-    ? ./build
+      ./build.dhall sha256:add7cb9acacac705410088d876a7e4488e046a7aded304f06c51accffd7f1b7b
+    ? ./build.dhall
 , even =
-      ./even sha256:72a05ee550636a3acb768360fa51ba0db0326763e0cf1ceb737f0f3607fc0fe5
-    ? ./even
+      ./even.dhall sha256:72a05ee550636a3acb768360fa51ba0db0326763e0cf1ceb737f0f3607fc0fe5
+    ? ./even.dhall
 , fold =
-      ./fold sha256:39f60baf3950268c2e849e91dc6279ee41cd6b81892d54020d4fcd2ce30a96ae
-    ? ./fold
+      ./fold.dhall sha256:39f60baf3950268c2e849e91dc6279ee41cd6b81892d54020d4fcd2ce30a96ae
+    ? ./fold.dhall
 , not =
-      ./not sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4
-    ? ./not
+      ./not.dhall sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4
+    ? ./not.dhall
 , odd =
-      ./odd sha256:6360fca3a745de32bd186cc7b71487a6398cd47d5119064eae491872c41d1999
-    ? ./odd
+      ./odd.dhall sha256:6360fca3a745de32bd186cc7b71487a6398cd47d5119064eae491872c41d1999
+    ? ./odd.dhall
 , or =
-      ./or sha256:5c50738e84e1c4fed8343ebd57608500e1b61ac1f502aa52d6d6edb5c20b99e4
-    ? ./or
+      ./or.dhall sha256:5c50738e84e1c4fed8343ebd57608500e1b61ac1f502aa52d6d6edb5c20b99e4
+    ? ./or.dhall
 , show =
-      ./show sha256:f85f6d2d921c37a2122cb2e2f8a0170e305b699debd0e6df5ef3370d806b5f61
-    ? ./show
+      ./show.dhall sha256:f85f6d2d921c37a2122cb2e2f8a0170e305b699debd0e6df5ef3370d806b5f61
+    ? ./show.dhall
 }
diff --git a/dhall-lang/Prelude/Double/package.dhall b/dhall-lang/Prelude/Double/package.dhall
--- a/dhall-lang/Prelude/Double/package.dhall
+++ b/dhall-lang/Prelude/Double/package.dhall
@@ -1,4 +1,4 @@
 { show =
-      ./show sha256:ae645813cc4d8505a265df4d7564c95482f62bb3e07fc81681959599b6cee04f
-    ? ./show
+      ./show.dhall sha256:ae645813cc4d8505a265df4d7564c95482f62bb3e07fc81681959599b6cee04f
+    ? ./show.dhall
 }
diff --git a/dhall-lang/Prelude/Function/package.dhall b/dhall-lang/Prelude/Function/package.dhall
--- a/dhall-lang/Prelude/Function/package.dhall
+++ b/dhall-lang/Prelude/Function/package.dhall
@@ -1,7 +1,7 @@
 { compose =
-      ./compose sha256:65ad8bbea530b3d8968785a7cf4a9a7976b67059aa15e3b61fcba600a40ae013
-    ? ./compose
+      ./compose.dhall sha256:65ad8bbea530b3d8968785a7cf4a9a7976b67059aa15e3b61fcba600a40ae013
+    ? ./compose.dhall
 , identity =
-      ./identity sha256:f78b96792b459cb664f41c6119bd8897dd04353a3343521d436cd82ad71cb4d4
-    ? ./identity
+      ./identity.dhall sha256:f78b96792b459cb664f41c6119bd8897dd04353a3343521d436cd82ad71cb4d4
+    ? ./identity.dhall
 }
diff --git a/dhall-lang/Prelude/Integer/add.dhall b/dhall-lang/Prelude/Integer/add.dhall
--- a/dhall-lang/Prelude/Integer/add.dhall
+++ b/dhall-lang/Prelude/Integer/add.dhall
@@ -1,7 +1,7 @@
 --| `add m n` computes `m + n`.
 let Integer/subtract =
-        ./subtract sha256:a34d36272fa8ae4f1ec8b56222fe8dc8a2ec55ec6538b840de0cbe207b006fda
-      ? ./subtract
+        ./subtract.dhall sha256:a34d36272fa8ae4f1ec8b56222fe8dc8a2ec55ec6538b840de0cbe207b006fda
+      ? ./subtract.dhall
 
 let add
     : Integer → Integer → Integer
diff --git a/dhall-lang/Prelude/Integer/equal.dhall b/dhall-lang/Prelude/Integer/equal.dhall
--- a/dhall-lang/Prelude/Integer/equal.dhall
+++ b/dhall-lang/Prelude/Integer/equal.dhall
@@ -1,7 +1,7 @@
 --| `equal` checks if two Integers are equal.
 let Natural/equal =
-        ../Natural/equal sha256:7f108edfa35ddc7cebafb24dc073478e93a802e13b5bc3fd22f4768c9b066e60
-      ? ../Natural/equal
+        ../Natural/equal.dhall sha256:7f108edfa35ddc7cebafb24dc073478e93a802e13b5bc3fd22f4768c9b066e60
+      ? ../Natural/equal.dhall
 
 let equal
     : Integer → Integer → Bool
diff --git a/dhall-lang/Prelude/Integer/greaterThan.dhall b/dhall-lang/Prelude/Integer/greaterThan.dhall
--- a/dhall-lang/Prelude/Integer/greaterThan.dhall
+++ b/dhall-lang/Prelude/Integer/greaterThan.dhall
@@ -1,11 +1,11 @@
 --| `greaterThan` checks if one Integer is greater than another.
 let Bool/not =
-        ../Bool/not sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4
-      ? ../Bool/not
+        ../Bool/not.dhall sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4
+      ? ../Bool/not.dhall
 
 let lessThanEqual =
-        ./lessThanEqual sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc
-      ? ./lessThanEqual
+        ./lessThanEqual.dhall sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc
+      ? ./lessThanEqual.dhall
 
 let greaterThan
     : Integer → Integer → Bool
diff --git a/dhall-lang/Prelude/Integer/greaterThanEqual.dhall b/dhall-lang/Prelude/Integer/greaterThanEqual.dhall
--- a/dhall-lang/Prelude/Integer/greaterThanEqual.dhall
+++ b/dhall-lang/Prelude/Integer/greaterThanEqual.dhall
@@ -2,8 +2,8 @@
 `greaterThanEqual` checks if one Integer is greater than or equal to another.
 -}
 let lessThanEqual =
-        ./lessThanEqual sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc
-      ? ./lessThanEqual
+        ./lessThanEqual.dhall sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc
+      ? ./lessThanEqual.dhall
 
 let greaterThanEqual
     : Integer → Integer → Bool
diff --git a/dhall-lang/Prelude/Integer/lessThan.dhall b/dhall-lang/Prelude/Integer/lessThan.dhall
--- a/dhall-lang/Prelude/Integer/lessThan.dhall
+++ b/dhall-lang/Prelude/Integer/lessThan.dhall
@@ -1,7 +1,7 @@
 --| `lessThan` checks if one Integer is less than another.
 let greaterThan =
-        ./greaterThan sha256:d23affd73029fc9aaf867c2c7b86510ca2802d3f0d1f3e1d1a93ffd87b7cb64b
-      ? ./greaterThan
+        ./greaterThan.dhall sha256:d23affd73029fc9aaf867c2c7b86510ca2802d3f0d1f3e1d1a93ffd87b7cb64b
+      ? ./greaterThan.dhall
 
 let lessThan
     : Integer → Integer → Bool
diff --git a/dhall-lang/Prelude/Integer/lessThanEqual.dhall b/dhall-lang/Prelude/Integer/lessThanEqual.dhall
--- a/dhall-lang/Prelude/Integer/lessThanEqual.dhall
+++ b/dhall-lang/Prelude/Integer/lessThanEqual.dhall
@@ -1,19 +1,19 @@
 --| `lessThanEqual` checks if one Integer is less than or equal to another.
 let Natural/greaterThanEqual =
-        ../Natural/greaterThanEqual sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4
-      ? ../Natural/greaterThanEqual
+        ../Natural/greaterThanEqual.dhall sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4
+      ? ../Natural/greaterThanEqual.dhall
 
 let Natural/lessThanEqual =
-        ../Natural/lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
-      ? ../Natural/lessThanEqual
+        ../Natural/lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
+      ? ../Natural/lessThanEqual.dhall
 
 let nonPositive =
-        ./nonPositive sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
-      ? ./nonPositive
+        ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
+      ? ./nonPositive.dhall
 
 let nonNegative =
-        ./nonNegative sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663
-      ? ./nonNegative
+        ./nonNegative.dhall sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663
+      ? ./nonNegative.dhall
 
 let lessThanEqual
     : Integer → Integer → Bool
diff --git a/dhall-lang/Prelude/Integer/multiply.dhall b/dhall-lang/Prelude/Integer/multiply.dhall
--- a/dhall-lang/Prelude/Integer/multiply.dhall
+++ b/dhall-lang/Prelude/Integer/multiply.dhall
@@ -1,8 +1,8 @@
 --| `multiply m n` computes `m * n`.
 
 let nonPositive =
-        ./nonPositive sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
-      ? ./nonPositive
+        ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
+      ? ./nonPositive.dhall
 
 let multiplyNonNegative =
       λ(x : Integer) →
diff --git a/dhall-lang/Prelude/Integer/negative.dhall b/dhall-lang/Prelude/Integer/negative.dhall
--- a/dhall-lang/Prelude/Integer/negative.dhall
+++ b/dhall-lang/Prelude/Integer/negative.dhall
@@ -4,8 +4,8 @@
 `negative` is more efficient than `./lessThan +0` or `./lessThanEqual -1`.
 -}
 let positive =
-        ./positive sha256:7bdbf50fcdb83d01f74c7e2a92bf5c9104eff5d8c5b4587e9337f0caefcfdbe3
-      ? ./positive
+        ./positive.dhall sha256:7bdbf50fcdb83d01f74c7e2a92bf5c9104eff5d8c5b4587e9337f0caefcfdbe3
+      ? ./positive.dhall
 
 let negative
     : Integer → Bool
diff --git a/dhall-lang/Prelude/Integer/nonNegative.dhall b/dhall-lang/Prelude/Integer/nonNegative.dhall
--- a/dhall-lang/Prelude/Integer/nonNegative.dhall
+++ b/dhall-lang/Prelude/Integer/nonNegative.dhall
@@ -4,8 +4,8 @@
 `nonNegative` is more efficient than `./greaterThanEqual +0` or `./greaterThan -1`.
 -}
 let nonPositive =
-        ./nonPositive sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
-      ? ./nonPositive
+        ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
+      ? ./nonPositive.dhall
 
 let nonNegative
     : Integer → Bool
diff --git a/dhall-lang/Prelude/Integer/package.dhall b/dhall-lang/Prelude/Integer/package.dhall
--- a/dhall-lang/Prelude/Integer/package.dhall
+++ b/dhall-lang/Prelude/Integer/package.dhall
@@ -1,55 +1,55 @@
 { abs =
-      ./abs sha256:35212fcbe1e60cb95b033a4a9c6e45befca4a298aa9919915999d09e69ddced1
-    ? ./abs
+      ./abs.dhall sha256:35212fcbe1e60cb95b033a4a9c6e45befca4a298aa9919915999d09e69ddced1
+    ? ./abs.dhall
 , add =
-      ./add sha256:7da1306a0bf87c5668beead2a1db1b18861e53d7ce1f38057b2964b649f59c3b
-    ? ./add
+      ./add.dhall sha256:7da1306a0bf87c5668beead2a1db1b18861e53d7ce1f38057b2964b649f59c3b
+    ? ./add.dhall
 , clamp =
-      ./clamp sha256:ea42096cf3e024fadfaf910e0b839005b0ea7514fff11e5a3950a77694d9c5d2
-    ? ./clamp
+      ./clamp.dhall sha256:ea42096cf3e024fadfaf910e0b839005b0ea7514fff11e5a3950a77694d9c5d2
+    ? ./clamp.dhall
 , equal =
-      ./equal sha256:2d99a205086aa77eea17ae1dab22c275f3eb007bccdc8d9895b93497ebfc39f8
-    ? ./equal
+      ./equal.dhall sha256:2d99a205086aa77eea17ae1dab22c275f3eb007bccdc8d9895b93497ebfc39f8
+    ? ./equal.dhall
 , greaterThan =
-      ./greaterThan sha256:d23affd73029fc9aaf867c2c7b86510ca2802d3f0d1f3e1d1a93ffd87b7cb64b
-    ? ./greaterThan
+      ./greaterThan.dhall sha256:d23affd73029fc9aaf867c2c7b86510ca2802d3f0d1f3e1d1a93ffd87b7cb64b
+    ? ./greaterThan.dhall
 , greaterThanEqual =
-      ./greaterThanEqual sha256:a9fa2dc5cd6067a23b39d7fe8d14a63109583b320429fb0e446658a5aae0a958
-    ? ./greaterThanEqual
+      ./greaterThanEqual.dhall sha256:a9fa2dc5cd6067a23b39d7fe8d14a63109583b320429fb0e446658a5aae0a958
+    ? ./greaterThanEqual.dhall
 , lessThan =
-      ./lessThan sha256:eeaa0081d10c6c97464ef193c40f1aa5cbb12f0202972ab42f3d310c2fd6a3f0
-    ? ./lessThan
+      ./lessThan.dhall sha256:eeaa0081d10c6c97464ef193c40f1aa5cbb12f0202972ab42f3d310c2fd6a3f0
+    ? ./lessThan.dhall
 , lessThanEqual =
-      ./lessThanEqual sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc
-    ? ./lessThanEqual
+      ./lessThanEqual.dhall sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc
+    ? ./lessThanEqual.dhall
 , multiply =
-      ./multiply sha256:dcb1ed7c8475ece8d67db92cd249fc728541778ff82509e28c3760e341880e4d
-    ? ./multiply
+      ./multiply.dhall sha256:dcb1ed7c8475ece8d67db92cd249fc728541778ff82509e28c3760e341880e4d
+    ? ./multiply.dhall
 , negate =
-      ./negate sha256:2373c992e1de93634bc6a8781eb073b2a92a70170133e49762a785f3a136df5d
-    ? ./negate
+      ./negate.dhall sha256:2373c992e1de93634bc6a8781eb073b2a92a70170133e49762a785f3a136df5d
+    ? ./negate.dhall
 , negative =
-      ./negative sha256:23e4b3c61eea9e878a7f83bf25fd0ea2c6a6d60174890d65be885828b690a570
-    ? ./negative
+      ./negative.dhall sha256:23e4b3c61eea9e878a7f83bf25fd0ea2c6a6d60174890d65be885828b690a570
+    ? ./negative.dhall
 , nonNegative =
-      ./nonNegative sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663
-    ? ./nonNegative
+      ./nonNegative.dhall sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663
+    ? ./nonNegative.dhall
 , nonPositive =
-      ./nonPositive sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
-    ? ./nonPositive
+      ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
+    ? ./nonPositive.dhall
 , positive =
-      ./positive sha256:7bdbf50fcdb83d01f74c7e2a92bf5c9104eff5d8c5b4587e9337f0caefcfdbe3
-    ? ./positive
+      ./positive.dhall sha256:7bdbf50fcdb83d01f74c7e2a92bf5c9104eff5d8c5b4587e9337f0caefcfdbe3
+    ? ./positive.dhall
 , show =
-      ./show sha256:ecf8b0594cd5181bc45d3b7ea0d44d3ba9ad5dac6ec17bb8968beb65f4b1baa9
-    ? ./show
+      ./show.dhall sha256:ecf8b0594cd5181bc45d3b7ea0d44d3ba9ad5dac6ec17bb8968beb65f4b1baa9
+    ? ./show.dhall
 , subtract =
-      ./subtract sha256:a34d36272fa8ae4f1ec8b56222fe8dc8a2ec55ec6538b840de0cbe207b006fda
-    ? ./subtract
+      ./subtract.dhall sha256:a34d36272fa8ae4f1ec8b56222fe8dc8a2ec55ec6538b840de0cbe207b006fda
+    ? ./subtract.dhall
 , toDouble =
-      ./toDouble sha256:77bc5d635dc4d952f37cc96f2a681d5ac503b4e8b21fc00055b1946adb5beda7
-    ? ./toDouble
+      ./toDouble.dhall sha256:77bc5d635dc4d952f37cc96f2a681d5ac503b4e8b21fc00055b1946adb5beda7
+    ? ./toDouble.dhall
 , toNatural =
-      ./toNatural sha256:4d128730d74e7f832e53873cb5204aa91b79758be5ce4e1aa991fe1951304a0e
-    ? ./toNatural
+      ./toNatural.dhall sha256:4d128730d74e7f832e53873cb5204aa91b79758be5ce4e1aa991fe1951304a0e
+    ? ./toNatural.dhall
 }
diff --git a/dhall-lang/Prelude/Integer/positive.dhall b/dhall-lang/Prelude/Integer/positive.dhall
--- a/dhall-lang/Prelude/Integer/positive.dhall
+++ b/dhall-lang/Prelude/Integer/positive.dhall
@@ -4,12 +4,12 @@
 `positive` is more efficient than `./greaterThan +0` or `./greaterThanEqual +1`.
 -}
 let not =
-        ../Bool/not sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4
-      ? ../Bool/not
+        ../Bool/not.dhall sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4
+      ? ../Bool/not.dhall
 
 let nonPositive =
-        ./nonPositive sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
-      ? ./nonPositive
+        ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
+      ? ./nonPositive.dhall
 
 let positive
     : Integer → Bool
diff --git a/dhall-lang/Prelude/Integer/subtract.dhall b/dhall-lang/Prelude/Integer/subtract.dhall
--- a/dhall-lang/Prelude/Integer/subtract.dhall
+++ b/dhall-lang/Prelude/Integer/subtract.dhall
@@ -1,7 +1,7 @@
 --| `subtract m n` computes `n - m`.
 let nonPositive =
-        ./nonPositive sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
-      ? ./nonPositive
+        ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
+      ? ./nonPositive.dhall
 
 let subtractNonNegative =
       λ(xi : Integer) →
diff --git a/dhall-lang/Prelude/Integer/toNatural.dhall b/dhall-lang/Prelude/Integer/toNatural.dhall
--- a/dhall-lang/Prelude/Integer/toNatural.dhall
+++ b/dhall-lang/Prelude/Integer/toNatural.dhall
@@ -2,8 +2,8 @@
 Convert an `Integer` to an `Optional Natural`, with negative numbers becoming `None Natural`.
 -}
 let nonNegative =
-        ./nonNegative sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663
-      ? ./nonNegative
+        ./nonNegative.dhall sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663
+      ? ./nonNegative.dhall
 
 let toNatural
     : Integer → Optional Natural
diff --git a/dhall-lang/Prelude/JSON/Tagged.dhall b/dhall-lang/Prelude/JSON/Tagged.dhall
--- a/dhall-lang/Prelude/JSON/Tagged.dhall
+++ b/dhall-lang/Prelude/JSON/Tagged.dhall
@@ -65,8 +65,8 @@
     = λ(a : Type) →
         { field : Text
         , nesting :
-              ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335
-            ? ./Nesting
+              ./Nesting.dhall sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335
+            ? ./Nesting.dhall
         , contents : a
         }
 
diff --git a/dhall-lang/Prelude/JSON/array.dhall b/dhall-lang/Prelude/JSON/array.dhall
--- a/dhall-lang/Prelude/JSON/array.dhall
+++ b/dhall-lang/Prelude/JSON/array.dhall
@@ -13,12 +13,12 @@
 ```
 -}
 let JSON =
-        ./Type sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
-      ? ./Type
+        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
+      ? ./Type.dhall
 
 let List/map =
-        ../List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
-      ? ../List/map
+        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
+      ? ../List/map.dhall
 
 let array
     : List JSON → JSON
diff --git a/dhall-lang/Prelude/JSON/bool.dhall b/dhall-lang/Prelude/JSON/bool.dhall
--- a/dhall-lang/Prelude/JSON/bool.dhall
+++ b/dhall-lang/Prelude/JSON/bool.dhall
@@ -12,8 +12,8 @@
 ```
 -}
 let JSON =
-        ./Type sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
-      ? ./Type
+        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
+      ? ./Type.dhall
 
 let bool
     : Bool → JSON
diff --git a/dhall-lang/Prelude/JSON/core.dhall b/dhall-lang/Prelude/JSON/core.dhall
--- a/dhall-lang/Prelude/JSON/core.dhall
+++ b/dhall-lang/Prelude/JSON/core.dhall
@@ -8,47 +8,47 @@
 `package.dhall` to avoid import cycles.
 -}
 { Type =
-      ./Type sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
-    ? ./Type
+      ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
+    ? ./Type.dhall
 , Tagged =
-      ./Tagged sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194
-    ? ./Tagged
+      ./Tagged.dhall sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194
+    ? ./Tagged.dhall
 , Nesting =
-      ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335
-    ? ./Nesting
+      ./Nesting.dhall sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335
+    ? ./Nesting.dhall
 , keyText =
-      ./keyText sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc
-    ? ./keyText
+      ./keyText.dhall sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc
+    ? ./keyText.dhall
 , keyValue =
-      ./keyValue sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c
-    ? ./keyValue
+      ./keyValue.dhall sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c
+    ? ./keyValue.dhall
 , string =
-      ./string sha256:7ddb3a3b9f3ed09ed011d621a10ad9825185cd03503be98a81d42f6afb77940e
-    ? ./string
+      ./string.dhall sha256:7ddb3a3b9f3ed09ed011d621a10ad9825185cd03503be98a81d42f6afb77940e
+    ? ./string.dhall
 , number =
-      ./number sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32
-    ? ./number
+      ./number.dhall sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32
+    ? ./number.dhall
 , double =
-      ./double sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32
-    ? ./double
+      ./double.dhall sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32
+    ? ./double.dhall
 , integer =
-      ./integer sha256:c81a417397fc6f62155ec71fdd8d2047f981f0881295b307de3dd88747bf7e40
-    ? ./integer
+      ./integer.dhall sha256:c81a417397fc6f62155ec71fdd8d2047f981f0881295b307de3dd88747bf7e40
+    ? ./integer.dhall
 , natural =
-      ./natural sha256:a839dc6789f19f820e9cbf70c60f41f3b057c59ece1d226d04db5aca447eb0e5
-    ? ./natural
+      ./natural.dhall sha256:a839dc6789f19f820e9cbf70c60f41f3b057c59ece1d226d04db5aca447eb0e5
+    ? ./natural.dhall
 , object =
-      ./object sha256:869aede785c34798be9f9fd457ece73e7f683f352ae4555f791516a365faf4ac
-    ? ./object
+      ./object.dhall sha256:869aede785c34798be9f9fd457ece73e7f683f352ae4555f791516a365faf4ac
+    ? ./object.dhall
 , array =
-      ./array sha256:fb6346a9c63638fe3c59f8108e19eebdbddc51389ec5570bab4c25f890ccccc8
-    ? ./array
+      ./array.dhall sha256:fb6346a9c63638fe3c59f8108e19eebdbddc51389ec5570bab4c25f890ccccc8
+    ? ./array.dhall
 , bool =
-      ./bool sha256:e043d9ed01e5b45899059e128243f3dae7ce65f293f0015ce816fc36d30f7f39
-    ? ./bool
+      ./bool.dhall sha256:e043d9ed01e5b45899059e128243f3dae7ce65f293f0015ce816fc36d30f7f39
+    ? ./bool.dhall
 , null =
-      ./null sha256:1eeb9aee38eb8dde0e64efbaf60f24612c8194cc00b510bfb627c2ee2e1877b8
-    ? ./null
+      ./null.dhall sha256:1eeb9aee38eb8dde0e64efbaf60f24612c8194cc00b510bfb627c2ee2e1877b8
+    ? ./null.dhall
 , renderInteger =
       ./renderInteger.dhall sha256:15b8d2ae46d5002832741927af787761df49798c911e2bf85db7a7b9cb5c078c
     ? ./renderInteger.dhall
diff --git a/dhall-lang/Prelude/JSON/double.dhall b/dhall-lang/Prelude/JSON/double.dhall
--- a/dhall-lang/Prelude/JSON/double.dhall
+++ b/dhall-lang/Prelude/JSON/double.dhall
@@ -12,8 +12,8 @@
 ```
 -}
 let JSON =
-        ./Type sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
-      ? ./Type
+        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
+      ? ./Type.dhall
 
 let double
     : Double → JSON
diff --git a/dhall-lang/Prelude/JSON/integer.dhall b/dhall-lang/Prelude/JSON/integer.dhall
--- a/dhall-lang/Prelude/JSON/integer.dhall
+++ b/dhall-lang/Prelude/JSON/integer.dhall
@@ -12,8 +12,8 @@
 ```
 -}
 let JSON =
-        ./Type sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
-      ? ./Type
+        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
+      ? ./Type.dhall
 
 let integer
     : Integer → JSON
diff --git a/dhall-lang/Prelude/JSON/keyText.dhall b/dhall-lang/Prelude/JSON/keyText.dhall
--- a/dhall-lang/Prelude/JSON/keyText.dhall
+++ b/dhall-lang/Prelude/JSON/keyText.dhall
@@ -1,2 +1,2 @@
-  ../Map/keyText sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc
-? ../Map/keyText
+  ../Map/keyText.dhall sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc
+? ../Map/keyText.dhall
diff --git a/dhall-lang/Prelude/JSON/keyValue.dhall b/dhall-lang/Prelude/JSON/keyValue.dhall
--- a/dhall-lang/Prelude/JSON/keyValue.dhall
+++ b/dhall-lang/Prelude/JSON/keyValue.dhall
@@ -1,2 +1,2 @@
-  ../Map/keyValue sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c
-? ../Map/keyValue
+  ../Map/keyValue.dhall sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c
+? ../Map/keyValue.dhall
diff --git a/dhall-lang/Prelude/JSON/natural.dhall b/dhall-lang/Prelude/JSON/natural.dhall
--- a/dhall-lang/Prelude/JSON/natural.dhall
+++ b/dhall-lang/Prelude/JSON/natural.dhall
@@ -8,8 +8,8 @@
 ```
 -}
 let JSON =
-        ./Type sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
-      ? ./Type
+        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
+      ? ./Type.dhall
 
 let natural
     : Natural → JSON
diff --git a/dhall-lang/Prelude/JSON/null.dhall b/dhall-lang/Prelude/JSON/null.dhall
--- a/dhall-lang/Prelude/JSON/null.dhall
+++ b/dhall-lang/Prelude/JSON/null.dhall
@@ -8,8 +8,8 @@
 ```
 -}
 let JSON =
-        ./Type sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
-      ? ./Type
+        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
+      ? ./Type.dhall
 
 let null
     : JSON
diff --git a/dhall-lang/Prelude/JSON/number.dhall b/dhall-lang/Prelude/JSON/number.dhall
--- a/dhall-lang/Prelude/JSON/number.dhall
+++ b/dhall-lang/Prelude/JSON/number.dhall
@@ -12,12 +12,12 @@
 ```
 -}
 let JSON =
-        ./Type sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
-      ? ./Type
+        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
+      ? ./Type.dhall
 
 let double =
-        ./double sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32
-      ? ./double
+        ./double.dhall sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32
+      ? ./double.dhall
 
 let number
     : Double → JSON
diff --git a/dhall-lang/Prelude/JSON/object.dhall b/dhall-lang/Prelude/JSON/object.dhall
--- a/dhall-lang/Prelude/JSON/object.dhall
+++ b/dhall-lang/Prelude/JSON/object.dhall
@@ -19,12 +19,12 @@
 ```
 -}
 let JSON =
-        ./Type sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
-      ? ./Type
+        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
+      ? ./Type.dhall
 
 let List/map =
-        ../List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
-      ? ../List/map
+        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
+      ? ../List/map.dhall
 
 let object
     : List { mapKey : Text, mapValue : JSON } → JSON
diff --git a/dhall-lang/Prelude/JSON/omitNullFields.dhall b/dhall-lang/Prelude/JSON/omitNullFields.dhall
--- a/dhall-lang/Prelude/JSON/omitNullFields.dhall
+++ b/dhall-lang/Prelude/JSON/omitNullFields.dhall
@@ -7,12 +7,12 @@
       ? ./core.dhall
 
 let List/concatMap =
-        ../List/concatMap sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64
-      ? ../List/concatMap
+        ../List/concatMap.dhall sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64
+      ? ../List/concatMap.dhall
 
 let List/map =
-        ../List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
-      ? ../List/map
+        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
+      ? ../List/map.dhall
 
 let omitNullFields
     : JSON.Type → JSON.Type
diff --git a/dhall-lang/Prelude/JSON/package.dhall b/dhall-lang/Prelude/JSON/package.dhall
--- a/dhall-lang/Prelude/JSON/package.dhall
+++ b/dhall-lang/Prelude/JSON/package.dhall
@@ -1,18 +1,18 @@
   { render =
-        ./render sha256:b5e5aee66b8fc018b50e1019a76340deafe5f8176854ea3611476d79990785da
-      ? ./render
+        ./render.dhall sha256:b5e5aee66b8fc018b50e1019a76340deafe5f8176854ea3611476d79990785da
+      ? ./render.dhall
   , renderYAML =
-        ./renderYAML sha256:dad92a120956ae852be7496d1e1955bbf3f60834ab2ad32641269098f2846477
-      ? ./renderYAML
+        ./renderYAML.dhall sha256:dad92a120956ae852be7496d1e1955bbf3f60834ab2ad32641269098f2846477
+      ? ./renderYAML.dhall
   , omitNullFields =
-        ./omitNullFields sha256:e6850e70094540b75edeb46f4d6038324a62def8d63544a1e9541f79739db6f0
-      ? ./omitNullFields
+        ./omitNullFields.dhall sha256:e6850e70094540b75edeb46f4d6038324a62def8d63544a1e9541f79739db6f0
+      ? ./omitNullFields.dhall
   , tagInline =
-        ./tagInline sha256:49559ac11906ba6cc9eac25753e31e7addb13bc760df108024174c55523984c4
-      ? ./tagInline
+        ./tagInline.dhall sha256:49559ac11906ba6cc9eac25753e31e7addb13bc760df108024174c55523984c4
+      ? ./tagInline.dhall
   , tagNested =
-        ./tagNested sha256:93a7415853b7677c832246efadc8e880c1b641a23589286a836a384ca311d26f
-      ? ./tagNested
+        ./tagNested.dhall sha256:93a7415853b7677c832246efadc8e880c1b641a23589286a836a384ca311d26f
+      ? ./tagNested.dhall
   }
 ∧ (   ./core.dhall sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5
     ? ./core.dhall
diff --git a/dhall-lang/Prelude/JSON/render.dhall b/dhall-lang/Prelude/JSON/render.dhall
--- a/dhall-lang/Prelude/JSON/render.dhall
+++ b/dhall-lang/Prelude/JSON/render.dhall
@@ -9,12 +9,12 @@
       ? ./core.dhall
 
 let renderAs =
-        ./renderAs sha256:5576473c02bc447d40d08bf103aaeca9637c1040367fdf07ff70032ba3e28043
-      ? ./renderAs
+        ./renderAs.dhall sha256:5576473c02bc447d40d08bf103aaeca9637c1040367fdf07ff70032ba3e28043
+      ? ./renderAs.dhall
 
 let Format =
-        ./Format sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac
-      ? ./Format
+        ./Format.dhall sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac
+      ? ./Format.dhall
 
 let render
     : JSON.Type → Text
diff --git a/dhall-lang/Prelude/JSON/renderAs.dhall b/dhall-lang/Prelude/JSON/renderAs.dhall
--- a/dhall-lang/Prelude/JSON/renderAs.dhall
+++ b/dhall-lang/Prelude/JSON/renderAs.dhall
@@ -5,20 +5,20 @@
       ? ./core.dhall
 
 let Function/identity =
-        ../Function/identity sha256:f78b96792b459cb664f41c6119bd8897dd04353a3343521d436cd82ad71cb4d4
-      ? ../Function/identity
+        ../Function/identity.dhall sha256:f78b96792b459cb664f41c6119bd8897dd04353a3343521d436cd82ad71cb4d4
+      ? ../Function/identity.dhall
 
 let Text/concatMap =
-        ../Text/concatMap sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f
-      ? ../Text/concatMap
+        ../Text/concatMap.dhall sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f
+      ? ../Text/concatMap.dhall
 
 let List/map =
-        ../List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
-      ? ../List/map
+        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
+      ? ../List/map.dhall
 
 let List/concatMap =
-        ../List/concatMap sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64
-      ? ../List/concatMap
+        ../List/concatMap.dhall sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64
+      ? ../List/concatMap.dhall
 
 let NonEmpty
     : Type → Type
@@ -190,8 +190,8 @@
 let indentTail = NonEmpty/mapTail Text addIndent
 
 let Format =
-        ./Format sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac
-      ? ./Format
+        ./Format.dhall sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac
+      ? ./Format.dhall
 
 let ObjectField = { mapKey : Text, mapValue : Block }
 
diff --git a/dhall-lang/Prelude/JSON/renderInteger.dhall b/dhall-lang/Prelude/JSON/renderInteger.dhall
--- a/dhall-lang/Prelude/JSON/renderInteger.dhall
+++ b/dhall-lang/Prelude/JSON/renderInteger.dhall
@@ -4,8 +4,8 @@
 -}
 
 let Integer/nonNegative =
-        ../Integer/nonNegative sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663
-      ? ../Integer/nonNegative
+        ../Integer/nonNegative.dhall sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663
+      ? ../Integer/nonNegative.dhall
 
 let renderInteger
     : Integer → Text
diff --git a/dhall-lang/Prelude/JSON/renderYAML.dhall b/dhall-lang/Prelude/JSON/renderYAML.dhall
--- a/dhall-lang/Prelude/JSON/renderYAML.dhall
+++ b/dhall-lang/Prelude/JSON/renderYAML.dhall
@@ -14,12 +14,12 @@
       ? ./core.dhall
 
 let renderAs =
-        ./renderAs sha256:5576473c02bc447d40d08bf103aaeca9637c1040367fdf07ff70032ba3e28043
-      ? ./renderAs
+        ./renderAs.dhall sha256:5576473c02bc447d40d08bf103aaeca9637c1040367fdf07ff70032ba3e28043
+      ? ./renderAs.dhall
 
 let Format =
-        ./Format sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac
-      ? ./Format
+        ./Format.dhall sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac
+      ? ./Format.dhall
 
 let renderYAML
     : JSON.Type → Text
diff --git a/dhall-lang/Prelude/JSON/string.dhall b/dhall-lang/Prelude/JSON/string.dhall
--- a/dhall-lang/Prelude/JSON/string.dhall
+++ b/dhall-lang/Prelude/JSON/string.dhall
@@ -12,8 +12,8 @@
 ```
 -}
 let JSON =
-        ./Type sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
-      ? ./Type
+        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
+      ? ./Type.dhall
 
 let string
     : Text → JSON
diff --git a/dhall-lang/Prelude/JSON/tagInline.dhall b/dhall-lang/Prelude/JSON/tagInline.dhall
--- a/dhall-lang/Prelude/JSON/tagInline.dhall
+++ b/dhall-lang/Prelude/JSON/tagInline.dhall
@@ -1,11 +1,11 @@
 --| Prepare a union value for JSON- or YAML-encoding with the inline layout
 let Nesting =
-        ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335
-      ? ./Nesting
+        ./Nesting.dhall sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335
+      ? ./Nesting.dhall
 
 let Tagged =
-        ./Tagged sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194
-      ? ./Tagged
+        ./Tagged.dhall sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194
+      ? ./Tagged.dhall
 
 let tagInline
     : Text → ∀(a : Type) → a → Tagged a
diff --git a/dhall-lang/Prelude/JSON/tagNested.dhall b/dhall-lang/Prelude/JSON/tagNested.dhall
--- a/dhall-lang/Prelude/JSON/tagNested.dhall
+++ b/dhall-lang/Prelude/JSON/tagNested.dhall
@@ -1,11 +1,11 @@
 --| Prepare a union value for JSON- or YAML-encoding with the nested layout
 let Nesting =
-        ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335
-      ? ./Nesting
+        ./Nesting.dhall sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335
+      ? ./Nesting.dhall
 
 let Tagged =
-        ./Tagged sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194
-      ? ./Tagged
+        ./Tagged.dhall sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194
+      ? ./Tagged.dhall
 
 let tagNested
     : Text → Text → ∀(a : Type) → a → Tagged a
diff --git a/dhall-lang/Prelude/List/drop.dhall b/dhall-lang/Prelude/List/drop.dhall
--- a/dhall-lang/Prelude/List/drop.dhall
+++ b/dhall-lang/Prelude/List/drop.dhall
@@ -1,7 +1,7 @@
 --| Remove first `n` elements of a list
 let Natural/greaterThanEqual =
-        ../Natural/greaterThanEqual sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4
-      ? ../Natural/greaterThanEqual
+        ../Natural/greaterThanEqual.dhall sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4
+      ? ../Natural/greaterThanEqual.dhall
 
 let drop
     : ∀(n : Natural) → ∀(a : Type) → List a → List a
diff --git a/dhall-lang/Prelude/List/index.dhall b/dhall-lang/Prelude/List/index.dhall
--- a/dhall-lang/Prelude/List/index.dhall
+++ b/dhall-lang/Prelude/List/index.dhall
@@ -1,7 +1,7 @@
 --| Retrieve an element from a `List` using its 0-based index
 let drop =
-        ./drop sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf
-      ? ./drop
+        ./drop.dhall sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf
+      ? ./drop.dhall
 
 let index
     : Natural → ∀(a : Type) → List a → Optional a
diff --git a/dhall-lang/Prelude/List/package.dhall b/dhall-lang/Prelude/List/package.dhall
--- a/dhall-lang/Prelude/List/package.dhall
+++ b/dhall-lang/Prelude/List/package.dhall
@@ -1,82 +1,82 @@
 { all =
-      ./all sha256:7ac5bb6f77e9ffe9e2356d90968d39764a9a32f75980206e6b12f815bb83dd15
-    ? ./all
+      ./all.dhall sha256:7ac5bb6f77e9ffe9e2356d90968d39764a9a32f75980206e6b12f815bb83dd15
+    ? ./all.dhall
 , any =
-      ./any sha256:b8e9e13b25e799f342a81f6eda4075906eb1a19dfdcb10a0ca25925eba4033b8
-    ? ./any
+      ./any.dhall sha256:b8e9e13b25e799f342a81f6eda4075906eb1a19dfdcb10a0ca25925eba4033b8
+    ? ./any.dhall
 , build =
-      ./build sha256:8cf73fc1e115cfcb79bb9cd490bfcbd45c824e93c57a0e64c86c0c72e9ebbe42
-    ? ./build
+      ./build.dhall sha256:8cf73fc1e115cfcb79bb9cd490bfcbd45c824e93c57a0e64c86c0c72e9ebbe42
+    ? ./build.dhall
 , concat =
-      ./concat sha256:54e43278be13276e03bd1afa89e562e94a0a006377ebea7db14c7562b0de292b
-    ? ./concat
+      ./concat.dhall sha256:54e43278be13276e03bd1afa89e562e94a0a006377ebea7db14c7562b0de292b
+    ? ./concat.dhall
 , concatMap =
-      ./concatMap sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64
-    ? ./concatMap
+      ./concatMap.dhall sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64
+    ? ./concatMap.dhall
 , default =
-      ./default sha256:fd77809e497227403f42848ffcda05a3efab442d961027c34f3e31d5d24e6379
-    ? ./default
+      ./default.dhall sha256:fd77809e497227403f42848ffcda05a3efab442d961027c34f3e31d5d24e6379
+    ? ./default.dhall
 , drop =
-      ./drop sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf
-    ? ./drop
+      ./drop.dhall sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf
+    ? ./drop.dhall
 , empty =
-      ./empty sha256:b2f561f35098c457353723c93a22bd5de28d26ecc5370814bef9dfda421e0147
-    ? ./empty
+      ./empty.dhall sha256:b2f561f35098c457353723c93a22bd5de28d26ecc5370814bef9dfda421e0147
+    ? ./empty.dhall
 , filter =
-      ./filter sha256:8ebfede5bbfe09675f246c33eb83964880ac615c4b1be8d856076fdbc4b26ba6
-    ? ./filter
+      ./filter.dhall sha256:8ebfede5bbfe09675f246c33eb83964880ac615c4b1be8d856076fdbc4b26ba6
+    ? ./filter.dhall
 , fold =
-      ./fold sha256:10bb945c25ab3943bd9df5a32e633cbfae112b7d3af38591784687e436a8d814
-    ? ./fold
+      ./fold.dhall sha256:10bb945c25ab3943bd9df5a32e633cbfae112b7d3af38591784687e436a8d814
+    ? ./fold.dhall
 , generate =
-      ./generate sha256:78ff1ad96c08b88a8263eea7bc8381c078225cfcb759c496f792edb5a5e0b1a4
-    ? ./generate
+      ./generate.dhall sha256:78ff1ad96c08b88a8263eea7bc8381c078225cfcb759c496f792edb5a5e0b1a4
+    ? ./generate.dhall
 , head =
-      ./head sha256:0d2e65ba0aea908377e46d22020dc3ad970284f4ee4eb8e6b8c51e53038c0026
-    ? ./head
+      ./head.dhall sha256:0d2e65ba0aea908377e46d22020dc3ad970284f4ee4eb8e6b8c51e53038c0026
+    ? ./head.dhall
 , index =
-      ./index sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63
-    ? ./index
+      ./index.dhall sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63
+    ? ./index.dhall
 , indexed =
-      ./indexed sha256:58bb44457fa81adf26f5123c1b2e8bef0c5aa22dac5fa5ebdfb7da84563b027f
-    ? ./indexed
+      ./indexed.dhall sha256:58bb44457fa81adf26f5123c1b2e8bef0c5aa22dac5fa5ebdfb7da84563b027f
+    ? ./indexed.dhall
 , iterate =
-      ./iterate sha256:e4999ccce190a2e2a6ab9cb188e3af6c40df474087827153005293f11bfe1d26
-    ? ./iterate
+      ./iterate.dhall sha256:e4999ccce190a2e2a6ab9cb188e3af6c40df474087827153005293f11bfe1d26
+    ? ./iterate.dhall
 , last =
-      ./last sha256:741226b741af152a1638491cdff7f3aa74baf080ada2e63429483f3d195a984d
-    ? ./last
+      ./last.dhall sha256:741226b741af152a1638491cdff7f3aa74baf080ada2e63429483f3d195a984d
+    ? ./last.dhall
 , length =
-      ./length sha256:42c6812c7a9e3c6e6fad88f77c5b3849503964e071cb784e22c38c888a401461
-    ? ./length
+      ./length.dhall sha256:42c6812c7a9e3c6e6fad88f77c5b3849503964e071cb784e22c38c888a401461
+    ? ./length.dhall
 , map =
-      ./map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
-    ? ./map
+      ./map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
+    ? ./map.dhall
 , null =
-      ./null sha256:2338e39637e9a50d66ae1482c0ed559bbcc11e9442bfca8f8c176bbcd9c4fc80
-    ? ./null
+      ./null.dhall sha256:2338e39637e9a50d66ae1482c0ed559bbcc11e9442bfca8f8c176bbcd9c4fc80
+    ? ./null.dhall
 , partition =
-      ./partition sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03
-    ? ./partition
+      ./partition.dhall sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03
+    ? ./partition.dhall
 , replicate =
-      ./replicate sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347
-    ? ./replicate
+      ./replicate.dhall sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347
+    ? ./replicate.dhall
 , reverse =
-      ./reverse sha256:ad99d224d61852de6696da5a7d04c98dbe676fe67d5e4ef4f19e9aaa27006e9d
-    ? ./reverse
+      ./reverse.dhall sha256:ad99d224d61852de6696da5a7d04c98dbe676fe67d5e4ef4f19e9aaa27006e9d
+    ? ./reverse.dhall
 , shifted =
-      ./shifted sha256:54fb22c7e952ebce1cfc0fcdd33ce4cfa817bff9d6564af268dea6685f8b5dfe
-    ? ./shifted
+      ./shifted.dhall sha256:54fb22c7e952ebce1cfc0fcdd33ce4cfa817bff9d6564af268dea6685f8b5dfe
+    ? ./shifted.dhall
 , take =
-      ./take sha256:b3e08ee8c3a5bf3d8ccee6b2b2008fbb8e51e7373aef6f1af67ad10078c9fbfa
-    ? ./take
+      ./take.dhall sha256:b3e08ee8c3a5bf3d8ccee6b2b2008fbb8e51e7373aef6f1af67ad10078c9fbfa
+    ? ./take.dhall
 , unpackOptionals =
-      ./unpackOptionals sha256:0cbaa920f429cf7fc3907f8a9143203fe948883913560e6e1043223e6b3d05e4
-    ? ./unpackOptionals
+      ./unpackOptionals.dhall sha256:0cbaa920f429cf7fc3907f8a9143203fe948883913560e6e1043223e6b3d05e4
+    ? ./unpackOptionals.dhall
 , unzip =
-      ./unzip sha256:4d6003e9e683a289fe33f4c90f958eb1e08ea0bbb474210fcd90d1885c9660e9
-    ? ./unzip
+      ./unzip.dhall sha256:4d6003e9e683a289fe33f4c90f958eb1e08ea0bbb474210fcd90d1885c9660e9
+    ? ./unzip.dhall
 , zip =
-      ./zip sha256:85ed955eabf3998767f4ad2a28e57d40cd4c68a95519d79e9b622f1d26d979da
-    ? ./zip
+      ./zip.dhall sha256:85ed955eabf3998767f4ad2a28e57d40cd4c68a95519d79e9b622f1d26d979da
+    ? ./zip.dhall
 }
diff --git a/dhall-lang/Prelude/List/take.dhall b/dhall-lang/Prelude/List/take.dhall
--- a/dhall-lang/Prelude/List/take.dhall
+++ b/dhall-lang/Prelude/List/take.dhall
@@ -1,7 +1,7 @@
 --| Truncate a list to the first `n` elements
 let Natural/lessThan =
-        ../Natural/lessThan sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c
-      ? ../Natural/lessThan
+        ../Natural/lessThan.dhall sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c
+      ? ../Natural/lessThan.dhall
 
 let take
     : ∀(n : Natural) → ∀(a : Type) → List a → List a
diff --git a/dhall-lang/Prelude/List/unpackOptionals.dhall b/dhall-lang/Prelude/List/unpackOptionals.dhall
--- a/dhall-lang/Prelude/List/unpackOptionals.dhall
+++ b/dhall-lang/Prelude/List/unpackOptionals.dhall
@@ -1,12 +1,12 @@
 --| Unpack Optionals in a List, omitting None items.
 
 let List/concatMap =
-        ./concatMap sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64
-      ? ./concatMap
+        ./concatMap.dhall sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64
+      ? ./concatMap.dhall
 
 let Optional/toList =
-        ../Optional/toList sha256:d78f160c619119ef12389e48a629ce293d69f7624c8d016b7a4767ab400344c4
-      ? ../Optional/toList
+        ../Optional/toList.dhall sha256:d78f160c619119ef12389e48a629ce293d69f7624c8d016b7a4767ab400344c4
+      ? ../Optional/toList.dhall
 
 let unpackOptionals
     : ∀(a : Type) → ∀(l : List (Optional a)) → List a
diff --git a/dhall-lang/Prelude/List/zip.dhall b/dhall-lang/Prelude/List/zip.dhall
--- a/dhall-lang/Prelude/List/zip.dhall
+++ b/dhall-lang/Prelude/List/zip.dhall
@@ -4,8 +4,8 @@
 The resulting `List` will have the length of the shortest of its arguments.
 -}
 let List/index =
-        ./index sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63
-      ? ./index
+        ./index.dhall sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63
+      ? ./index.dhall
 
 let zip
     : ∀(a : Type) → List a → ∀(b : Type) → List b → List { _1 : a, _2 : b }
diff --git a/dhall-lang/Prelude/Location/package.dhall b/dhall-lang/Prelude/Location/package.dhall
--- a/dhall-lang/Prelude/Location/package.dhall
+++ b/dhall-lang/Prelude/Location/package.dhall
@@ -1,4 +1,4 @@
 { Type =
-      ./Type sha256:613ebb491aeef4ff06368058b4f0e6e3bb8a58d8c145131fc0b947aac045a529
-    ? ./Type
+      ./Type.dhall sha256:613ebb491aeef4ff06368058b4f0e6e3bb8a58d8c145131fc0b947aac045a529
+    ? ./Type.dhall
 }
diff --git a/dhall-lang/Prelude/Map/empty.dhall b/dhall-lang/Prelude/Map/empty.dhall
--- a/dhall-lang/Prelude/Map/empty.dhall
+++ b/dhall-lang/Prelude/Map/empty.dhall
@@ -1,7 +1,7 @@
 --| An empty `Map` of the given key and value types
 let Map =
-        ./Type sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
-      ? ./Type
+        ./Type.dhall sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
+      ? ./Type.dhall
 
 let empty
     : ∀(k : Type) → ∀(v : Type) → Map k v
diff --git a/dhall-lang/Prelude/Map/keys.dhall b/dhall-lang/Prelude/Map/keys.dhall
--- a/dhall-lang/Prelude/Map/keys.dhall
+++ b/dhall-lang/Prelude/Map/keys.dhall
@@ -1,11 +1,11 @@
 --| Get all of the keys of a `Map` as a `List`
 let Map =
-        ./Type sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
-      ? ./Type
+        ./Type.dhall sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
+      ? ./Type.dhall
 
 let Entry =
-        ./Entry sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346
-      ? ./Entry
+        ./Entry.dhall sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346
+      ? ./Entry.dhall
 
 let List/map =
         ../List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
diff --git a/dhall-lang/Prelude/Map/map.dhall b/dhall-lang/Prelude/Map/map.dhall
--- a/dhall-lang/Prelude/Map/map.dhall
+++ b/dhall-lang/Prelude/Map/map.dhall
@@ -1,15 +1,15 @@
 --| Transform a `Map` by applying a function to each value
 let Map =
-        ./Type sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
-      ? ./Type
+        ./Type.dhall sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
+      ? ./Type.dhall
 
 let Entry =
-        ./Entry sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346
-      ? ./Entry
+        ./Entry.dhall sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346
+      ? ./Entry.dhall
 
 let List/map =
-        ../List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
-      ? ../List/map
+        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
+      ? ../List/map.dhall
 
 let map
     : ∀(k : Type) → ∀(a : Type) → ∀(b : Type) → (a → b) → Map k a → Map k b
diff --git a/dhall-lang/Prelude/Map/package.dhall b/dhall-lang/Prelude/Map/package.dhall
--- a/dhall-lang/Prelude/Map/package.dhall
+++ b/dhall-lang/Prelude/Map/package.dhall
@@ -19,6 +19,9 @@
 , map =
       ./map sha256:23e09b0b9f08649797dfe1ca39755d5e1c7cad2d0944bdd36c7a0bf804bde8d0
     ? ./map
+, unpackOptionals =
+      ./unpackOptionals.dhall sha256:66c3e6f6f81418cf99342e1dba739617c01af4b27c1ca5e2e1d7bce64a522e22
+    ? ./unpackOptionals.dhall
 , values =
       ./values sha256:ae02cfb06a9307cbecc06130e84fd0c7b96b7f1f11648961e1b030ec00940be8
     ? ./values
diff --git a/dhall-lang/Prelude/Map/unpackOptionals.dhall b/dhall-lang/Prelude/Map/unpackOptionals.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/Prelude/Map/unpackOptionals.dhall
@@ -0,0 +1,39 @@
+--| Turn a `Map k (Optional v)` into a `Map k v` by dropping all
+--  entries with value `None`.
+
+let List/concatMap =
+        ../List/concatMap.dhall sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64
+      ? ../List/concatMap.dhall
+
+let Map/Entry =
+        ./Entry.dhall sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346
+      ? ./Entry.dhall
+
+let Map/Type =
+        ./Type.dhall sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
+      ? ./Type.dhall
+
+let unpackOptionals
+    : ∀(k : Type) → ∀(v : Type) → Map/Type k (Optional v) → Map/Type k v
+    = λ(k : Type) →
+      λ(v : Type) →
+        List/concatMap
+          (Map/Entry k (Optional v))
+          (Map/Entry k v)
+          ( λ(e : Map/Entry k (Optional v)) →
+              merge
+                { None = [] : Map/Type k v
+                , Some = λ(v : v) → [ { mapKey = e.mapKey, mapValue = v } ]
+                }
+                e.mapValue
+          )
+
+let example0 =
+        assert
+      :   unpackOptionals
+            Text
+            Text
+            (toMap { foo = Some "bar", baz = None Text })
+        ≡ toMap { foo = "bar" }
+
+in  unpackOptionals
diff --git a/dhall-lang/Prelude/Map/values.dhall b/dhall-lang/Prelude/Map/values.dhall
--- a/dhall-lang/Prelude/Map/values.dhall
+++ b/dhall-lang/Prelude/Map/values.dhall
@@ -1,15 +1,15 @@
 --| Get all of the values of a `Map` as a `List`
 let Map =
-        ./Type sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
-      ? ./Type
+        ./Type.dhall sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed
+      ? ./Type.dhall
 
 let Entry =
-        ./Entry sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346
-      ? ./Entry
+        ./Entry.dhall sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346
+      ? ./Entry.dhall
 
 let List/map =
-        ../List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
-      ? ../List/map
+        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
+      ? ../List/map.dhall
 
 let values
     : ∀(k : Type) → ∀(v : Type) → Map k v → List v
diff --git a/dhall-lang/Prelude/Natural/equal.dhall b/dhall-lang/Prelude/Natural/equal.dhall
--- a/dhall-lang/Prelude/Natural/equal.dhall
+++ b/dhall-lang/Prelude/Natural/equal.dhall
@@ -1,7 +1,7 @@
 --| `equal` checks if two Naturals are equal.
 let lessThanEqual =
-        ./lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
-      ? ./lessThanEqual
+        ./lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
+      ? ./lessThanEqual.dhall
 
 let equal
     : Natural → Natural → Bool
diff --git a/dhall-lang/Prelude/Natural/greaterThan.dhall b/dhall-lang/Prelude/Natural/greaterThan.dhall
--- a/dhall-lang/Prelude/Natural/greaterThan.dhall
+++ b/dhall-lang/Prelude/Natural/greaterThan.dhall
@@ -1,7 +1,7 @@
 --| `greaterThan` checks if one Natural is strictly greater than another.
 let lessThan =
-        ./lessThan sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c
-      ? ./lessThan
+        ./lessThan.dhall sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c
+      ? ./lessThan.dhall
 
 let greaterThan
     : Natural → Natural → Bool
diff --git a/dhall-lang/Prelude/Natural/greaterThanEqual.dhall b/dhall-lang/Prelude/Natural/greaterThanEqual.dhall
--- a/dhall-lang/Prelude/Natural/greaterThanEqual.dhall
+++ b/dhall-lang/Prelude/Natural/greaterThanEqual.dhall
@@ -2,8 +2,8 @@
 `greaterThanEqual` checks if one Natural is greater than or equal to another.
 -}
 let lessThanEqual =
-        ./lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
-      ? ./lessThanEqual
+        ./lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
+      ? ./lessThanEqual.dhall
 
 let greaterThanEqual
     : Natural → Natural → Bool
diff --git a/dhall-lang/Prelude/Natural/lessThan.dhall b/dhall-lang/Prelude/Natural/lessThan.dhall
--- a/dhall-lang/Prelude/Natural/lessThan.dhall
+++ b/dhall-lang/Prelude/Natural/lessThan.dhall
@@ -1,11 +1,11 @@
 --| `lessThan` checks if one Natural is strictly less than another.
 let greaterThanEqual =
-        ./greaterThanEqual sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4
-      ? ./greaterThanEqual
+        ./greaterThanEqual.dhall sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4
+      ? ./greaterThanEqual.dhall
 
 let Bool/not =
-        ../Bool/not sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4
-      ? ../Bool/not
+        ../Bool/not.dhall sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4
+      ? ../Bool/not.dhall
 
 let lessThan
     : Natural → Natural → Bool
diff --git a/dhall-lang/Prelude/Natural/listMax.dhall b/dhall-lang/Prelude/Natural/listMax.dhall
--- a/dhall-lang/Prelude/Natural/listMax.dhall
+++ b/dhall-lang/Prelude/Natural/listMax.dhall
@@ -3,12 +3,12 @@
 `List` is empty
 -}
 let max =
-        ./max sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7
-      ? ./max
+        ./max.dhall sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7
+      ? ./max.dhall
 
 let Optional/map =
-        ../Optional/map sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa
-      ? ../Optional/map
+        ../Optional/map.dhall sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa
+      ? ../Optional/map.dhall
 
 let listMax
     : List Natural → Optional Natural
diff --git a/dhall-lang/Prelude/Natural/listMin.dhall b/dhall-lang/Prelude/Natural/listMin.dhall
--- a/dhall-lang/Prelude/Natural/listMin.dhall
+++ b/dhall-lang/Prelude/Natural/listMin.dhall
@@ -3,12 +3,12 @@
 `List` is empty
 -}
 let min =
-        ./min sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710
-      ? ./min
+        ./min.dhall sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710
+      ? ./min.dhall
 
 let Optional/map =
-        ../Optional/map sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa
-      ? ../Optional/map
+        ../Optional/map.dhall sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa
+      ? ../Optional/map.dhall
 
 let listMin
     : List Natural → Optional Natural
diff --git a/dhall-lang/Prelude/Natural/max.dhall b/dhall-lang/Prelude/Natural/max.dhall
--- a/dhall-lang/Prelude/Natural/max.dhall
+++ b/dhall-lang/Prelude/Natural/max.dhall
@@ -1,7 +1,7 @@
 --| `max a b` returns the larger of `a` or `b`
 let lessThanEqual =
-        ./lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
-      ? ./lessThanEqual
+        ./lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
+      ? ./lessThanEqual.dhall
 
 let max
     : Natural → Natural → Natural
diff --git a/dhall-lang/Prelude/Natural/min.dhall b/dhall-lang/Prelude/Natural/min.dhall
--- a/dhall-lang/Prelude/Natural/min.dhall
+++ b/dhall-lang/Prelude/Natural/min.dhall
@@ -1,7 +1,7 @@
 --| `min a b` returns the smaller of `a` or `b`
 let lessThanEqual =
-        ./lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
-      ? ./lessThanEqual
+        ./lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
+      ? ./lessThanEqual.dhall
 
 let min
     : Natural → Natural → Natural
diff --git a/dhall-lang/Prelude/Natural/package.dhall b/dhall-lang/Prelude/Natural/package.dhall
--- a/dhall-lang/Prelude/Natural/package.dhall
+++ b/dhall-lang/Prelude/Natural/package.dhall
@@ -1,67 +1,67 @@
 { build =
-      ./build sha256:e7e25e6c4f1d8e573606ed1bef725396ac2de5c68f7c5d329ffc5822085b984c
-    ? ./build
+      ./build.dhall sha256:e7e25e6c4f1d8e573606ed1bef725396ac2de5c68f7c5d329ffc5822085b984c
+    ? ./build.dhall
 , enumerate =
-      ./enumerate sha256:0cf083980a752b21ce0df9fc2222a4c139f50909e2353576e26a191002aa1ce3
-    ? ./enumerate
+      ./enumerate.dhall sha256:0cf083980a752b21ce0df9fc2222a4c139f50909e2353576e26a191002aa1ce3
+    ? ./enumerate.dhall
 , even =
-      ./even sha256:b85b8b56892dfef881e1c0e79eade0b949528f792aac0ea42432b315ede4ee66
-    ? ./even
+      ./even.dhall sha256:b85b8b56892dfef881e1c0e79eade0b949528f792aac0ea42432b315ede4ee66
+    ? ./even.dhall
 , fold =
-      ./fold sha256:fd01c931e585a8f5fd049af7b076b862ea164f1813b34800c7616a49e549ee06
-    ? ./fold
+      ./fold.dhall sha256:fd01c931e585a8f5fd049af7b076b862ea164f1813b34800c7616a49e549ee06
+    ? ./fold.dhall
 , isZero =
-      ./isZero sha256:1be98236800ed2d5cff44f16ca02b34b0c37dfa239d9e0d63d9d2c6eeae3d1d1
-    ? ./isZero
+      ./isZero.dhall sha256:1be98236800ed2d5cff44f16ca02b34b0c37dfa239d9e0d63d9d2c6eeae3d1d1
+    ? ./isZero.dhall
 , odd =
-      ./odd sha256:ab3c729262c642ec1cdb72a81e910fcfaf2aea13e3961d0bf1bec83efea5aac5
-    ? ./odd
+      ./odd.dhall sha256:ab3c729262c642ec1cdb72a81e910fcfaf2aea13e3961d0bf1bec83efea5aac5
+    ? ./odd.dhall
 , product =
-      ./product sha256:e3e6fd76207875b81d39f79fdbc90b5e640444c04fb3d84c2c9326748f0b26e6
-    ? ./product
+      ./product.dhall sha256:e3e6fd76207875b81d39f79fdbc90b5e640444c04fb3d84c2c9326748f0b26e6
+    ? ./product.dhall
 , sum =
-      ./sum sha256:33f7f4c3aff62e5ecf4848f964363133452d420dcde045784518fb59fa970037
-    ? ./sum
+      ./sum.dhall sha256:33f7f4c3aff62e5ecf4848f964363133452d420dcde045784518fb59fa970037
+    ? ./sum.dhall
 , show =
-      ./show sha256:684ed560ad86f438efdea229eca122c29e8e14f397ed32ec97148d578ca5aa21
-    ? ./show
+      ./show.dhall sha256:684ed560ad86f438efdea229eca122c29e8e14f397ed32ec97148d578ca5aa21
+    ? ./show.dhall
 , toDouble =
-      ./toDouble sha256:d5eb52143dcd35b46a6f0cdb2d3cbf31a14b6daeba56e29066f8e344c9fb6e81
-    ? ./toDouble
+      ./toDouble.dhall sha256:d5eb52143dcd35b46a6f0cdb2d3cbf31a14b6daeba56e29066f8e344c9fb6e81
+    ? ./toDouble.dhall
 , toInteger =
-      ./toInteger sha256:160d2d278619f3da34a1f4f02e739a447e4f2aa5a2978c45b710515b41491e1f
-    ? ./toInteger
+      ./toInteger.dhall sha256:160d2d278619f3da34a1f4f02e739a447e4f2aa5a2978c45b710515b41491e1f
+    ? ./toInteger.dhall
 , lessThan =
-      ./lessThan sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c
-    ? ./lessThan
+      ./lessThan.dhall sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c
+    ? ./lessThan.dhall
 , lessThanEqual =
-      ./lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
-    ? ./lessThanEqual
+      ./lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99
+    ? ./lessThanEqual.dhall
 , equal =
-      ./equal sha256:7f108edfa35ddc7cebafb24dc073478e93a802e13b5bc3fd22f4768c9b066e60
-    ? ./equal
+      ./equal.dhall sha256:7f108edfa35ddc7cebafb24dc073478e93a802e13b5bc3fd22f4768c9b066e60
+    ? ./equal.dhall
 , greaterThanEqual =
-      ./greaterThanEqual sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4
-    ? ./greaterThanEqual
+      ./greaterThanEqual.dhall sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4
+    ? ./greaterThanEqual.dhall
 , greaterThan =
-      ./greaterThan sha256:f702abcdfcd7ad73619b9285d7e41c3a1d017fb6b8d037cf40bd93bf30c09b2c
-    ? ./greaterThan
+      ./greaterThan.dhall sha256:f702abcdfcd7ad73619b9285d7e41c3a1d017fb6b8d037cf40bd93bf30c09b2c
+    ? ./greaterThan.dhall
 , min =
-      ./min sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710
-    ? ./min
+      ./min.dhall sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710
+    ? ./min.dhall
 , max =
-      ./max sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7
-    ? ./max
+      ./max.dhall sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7
+    ? ./max.dhall
 , listMin =
-      ./listMin sha256:ee70b0d010bbca6012162e8ae1f6e9d9bd10a152675509b0f23145b98b5d43c6
-    ? ./listMin
+      ./listMin.dhall sha256:ee70b0d010bbca6012162e8ae1f6e9d9bd10a152675509b0f23145b98b5d43c6
+    ? ./listMin.dhall
 , listMax =
-      ./listMax sha256:20906ffcc9970f740106d4516cb7868b43d75ff8c9f00ff8a9680ae68c48a472
-    ? ./listMax
+      ./listMax.dhall sha256:20906ffcc9970f740106d4516cb7868b43d75ff8c9f00ff8a9680ae68c48a472
+    ? ./listMax.dhall
 , sort =
-      ./sort sha256:36ce8b3e5538454763987ca904d8d7c5ba34c2147434a19eddd51f684432b260
-    ? ./sort
+      ./sort.dhall sha256:36ce8b3e5538454763987ca904d8d7c5ba34c2147434a19eddd51f684432b260
+    ? ./sort.dhall
 , subtract =
-      ./subtract sha256:b9277ac637d09142a3a3ac79137ef5955c42f8b33b6746d59db2c9d75ccdd745
-    ? ./subtract
+      ./subtract.dhall sha256:b9277ac637d09142a3a3ac79137ef5955c42f8b33b6746d59db2c9d75ccdd745
+    ? ./subtract.dhall
 }
diff --git a/dhall-lang/Prelude/Natural/sort.dhall b/dhall-lang/Prelude/Natural/sort.dhall
--- a/dhall-lang/Prelude/Natural/sort.dhall
+++ b/dhall-lang/Prelude/Natural/sort.dhall
@@ -1,15 +1,15 @@
 --| `sort` sorts a `List` of `Natural`s in ascending order
 let greaterThanEqual =
-        ./greaterThanEqual sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4
-      ? ./greaterThanEqual
+        ./greaterThanEqual.dhall sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4
+      ? ./greaterThanEqual.dhall
 
 let listMin =
-        ./listMin sha256:ee70b0d010bbca6012162e8ae1f6e9d9bd10a152675509b0f23145b98b5d43c6
-      ? ./listMin
+        ./listMin.dhall sha256:ee70b0d010bbca6012162e8ae1f6e9d9bd10a152675509b0f23145b98b5d43c6
+      ? ./listMin.dhall
 
 let List/partition =
-        ../List/partition sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03
-      ? ../List/partition
+        ../List/partition.dhall sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03
+      ? ../List/partition.dhall
 
 let Accumulator = { sorted : List Natural, rest : List Natural }
 
diff --git a/dhall-lang/Prelude/Optional/package.dhall b/dhall-lang/Prelude/Optional/package.dhall
--- a/dhall-lang/Prelude/Optional/package.dhall
+++ b/dhall-lang/Prelude/Optional/package.dhall
@@ -1,43 +1,43 @@
 { all =
-      ./all sha256:a303004b6def0a2a05bf5f0a8d54e84dd45d8bef581789186ac04924956a1695
-    ? ./all
+      ./all.dhall sha256:a303004b6def0a2a05bf5f0a8d54e84dd45d8bef581789186ac04924956a1695
+    ? ./all.dhall
 , any =
-      ./any sha256:96a5cf4f31b3c598b09161dd3082f0a09f4328a4cefda6a7e09894b37b17b435
-    ? ./any
+      ./any.dhall sha256:96a5cf4f31b3c598b09161dd3082f0a09f4328a4cefda6a7e09894b37b17b435
+    ? ./any.dhall
 , build =
-      ./build sha256:28e61294bf2dd59dc57cf74f719d1568e60b5ba46c28eac586bc937eff4a2af1
-    ? ./build
+      ./build.dhall sha256:28e61294bf2dd59dc57cf74f719d1568e60b5ba46c28eac586bc937eff4a2af1
+    ? ./build.dhall
 , concat =
-      ./concat sha256:b7736bd3ebeab14c3912dfb534d0c970a025b001d06c2d5461d4b0e289e3cb7a
-    ? ./concat
+      ./concat.dhall sha256:b7736bd3ebeab14c3912dfb534d0c970a025b001d06c2d5461d4b0e289e3cb7a
+    ? ./concat.dhall
 , default =
-      ./default sha256:5bd665b0d6605c374b3c4a7e2e2bd3b9c1e39323d41441149ed5e30d86e889ad
-    ? ./default
+      ./default.dhall sha256:5bd665b0d6605c374b3c4a7e2e2bd3b9c1e39323d41441149ed5e30d86e889ad
+    ? ./default.dhall
 , filter =
-      ./filter sha256:54f0a487d578801819613fe000050c038c632edf1f9ccc57677e98ae0ef56b83
-    ? ./filter
+      ./filter.dhall sha256:54f0a487d578801819613fe000050c038c632edf1f9ccc57677e98ae0ef56b83
+    ? ./filter.dhall
 , fold =
-      ./fold sha256:c5b9d72f6f62bdaa0e196ac1c742cc175cd67a717b880fb8aec1333a5a4132cf
-    ? ./fold
+      ./fold.dhall sha256:c5b9d72f6f62bdaa0e196ac1c742cc175cd67a717b880fb8aec1333a5a4132cf
+    ? ./fold.dhall
 , head =
-      ./head sha256:4f256c9338b60a1933f41f2a8fafd861930a1e41770a644cdbac0622676fa34c
-    ? ./head
+      ./head.dhall sha256:4f256c9338b60a1933f41f2a8fafd861930a1e41770a644cdbac0622676fa34c
+    ? ./head.dhall
 , last =
-      ./last sha256:50400771ae19e9b75efa6581feec318ae1ade0b6a60e215df428c66c4b052707
-    ? ./last
+      ./last.dhall sha256:50400771ae19e9b75efa6581feec318ae1ade0b6a60e215df428c66c4b052707
+    ? ./last.dhall
 , length =
-      ./length sha256:f168337c5244ded68c05ecf32ce068b6b87158881d07e87b8cb6853fc6982a85
-    ? ./length
+      ./length.dhall sha256:f168337c5244ded68c05ecf32ce068b6b87158881d07e87b8cb6853fc6982a85
+    ? ./length.dhall
 , map =
-      ./map sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa
-    ? ./map
+      ./map.dhall sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa
+    ? ./map.dhall
 , null =
-      ./null sha256:3871180b87ecaba8b53fffb2a8b52d3fce98098fab09a6f759358b9e8042eedc
-    ? ./null
+      ./null.dhall sha256:3871180b87ecaba8b53fffb2a8b52d3fce98098fab09a6f759358b9e8042eedc
+    ? ./null.dhall
 , toList =
-      ./toList sha256:d78f160c619119ef12389e48a629ce293d69f7624c8d016b7a4767ab400344c4
-    ? ./toList
+      ./toList.dhall sha256:d78f160c619119ef12389e48a629ce293d69f7624c8d016b7a4767ab400344c4
+    ? ./toList.dhall
 , unzip =
-      ./unzip sha256:d016c01ba91657a2f35609aa29087963d0f506bab0f41d5e8b7cd289dff39708
-    ? ./unzip
+      ./unzip.dhall sha256:d016c01ba91657a2f35609aa29087963d0f506bab0f41d5e8b7cd289dff39708
+    ? ./unzip.dhall
 }
diff --git a/dhall-lang/Prelude/Text/package.dhall b/dhall-lang/Prelude/Text/package.dhall
--- a/dhall-lang/Prelude/Text/package.dhall
+++ b/dhall-lang/Prelude/Text/package.dhall
@@ -1,28 +1,28 @@
 { concat =
-      ./concat sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0
-    ? ./concat
+      ./concat.dhall sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0
+    ? ./concat.dhall
 , concatMap =
-      ./concatMap sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f
-    ? ./concatMap
+      ./concatMap.dhall sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f
+    ? ./concatMap.dhall
 , concatMapSep =
-      ./concatMapSep sha256:c272aca80a607bc5963d1fcb38819e7e0d3e72ac4d02b1183b1afb6a91340840
-    ? ./concatMapSep
+      ./concatMapSep.dhall sha256:c272aca80a607bc5963d1fcb38819e7e0d3e72ac4d02b1183b1afb6a91340840
+    ? ./concatMapSep.dhall
 , concatSep =
-      ./concatSep sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58
-    ? ./concatSep
+      ./concatSep.dhall sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58
+    ? ./concatSep.dhall
 , default =
-      ./default sha256:f532c8891b1e427d90a6cc07cf7e793a4c84b0765e1bfe69f186ee2ec91c1edf
-    ? ./default
+      ./default.dhall sha256:f532c8891b1e427d90a6cc07cf7e793a4c84b0765e1bfe69f186ee2ec91c1edf
+    ? ./default.dhall
 , defaultMap =
-      ./defaultMap sha256:3a3fa1264f6198800c27483cb144de2c5366484876d60b9c739a710ce0288588
-    ? ./defaultMap
+      ./defaultMap.dhall sha256:3a3fa1264f6198800c27483cb144de2c5366484876d60b9c739a710ce0288588
+    ? ./defaultMap.dhall
 , replicate =
-      ./replicate sha256:1b398b1d464b3a6c7264a690ac3cacb443b5683b43348c859d68e7c2cb925c4f
-    ? ./replicate
+      ./replicate.dhall sha256:1b398b1d464b3a6c7264a690ac3cacb443b5683b43348c859d68e7c2cb925c4f
+    ? ./replicate.dhall
 , show =
-      ./show sha256:c9dc5de3e5f32872dbda57166804865e5e80785abe358ff61f1d8ac45f1f4784
-    ? ./show
+      ./show.dhall sha256:c9dc5de3e5f32872dbda57166804865e5e80785abe358ff61f1d8ac45f1f4784
+    ? ./show.dhall
 , spaces =
-      ./spaces sha256:fccfd4f26601e006bf6a79ca948dbd37c676cdd0db439554447320293d23b3dc
-    ? ./spaces
+      ./spaces.dhall sha256:fccfd4f26601e006bf6a79ca948dbd37c676cdd0db439554447320293d23b3dc
+    ? ./spaces.dhall
 }
diff --git a/dhall-lang/Prelude/Text/replace.dhall b/dhall-lang/Prelude/Text/replace.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/Prelude/Text/replace.dhall
@@ -0,0 +1,14 @@
+{-
+Replace a section of `Text` with another inside a `Text` literal.
+-}
+let replace
+    : ∀(needle : Text) → ∀(replacement : Text) → ∀(haystack : Text) → Text
+    = Text/replace
+
+let example0 = assert : replace "-" "_" "foo-bar" ≡ "foo_bar"
+
+let example1 = assert : replace "💣" "💥" "💣💣💣" ≡ "💥💥💥"
+
+let example2 = assert : replace "👨" "👩" "👨‍👩‍👧‍👦" ≡ "👩‍👩‍👧‍👦"
+
+in  replace
diff --git a/dhall-lang/Prelude/Text/replicate.dhall b/dhall-lang/Prelude/Text/replicate.dhall
--- a/dhall-lang/Prelude/Text/replicate.dhall
+++ b/dhall-lang/Prelude/Text/replicate.dhall
@@ -1,12 +1,12 @@
 --| Build a Text by copying the given Text the specified number of times
 
 let concat =
-        ./concat sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0
-      ? ./concat
+        ./concat.dhall sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0
+      ? ./concat.dhall
 
 let List/replicate =
-        ../List/replicate sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347
-      ? ../List/replicate
+        ../List/replicate.dhall sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347
+      ? ../List/replicate.dhall
 
 let replicate
     : Natural → Text → Text
diff --git a/dhall-lang/Prelude/Text/spaces.dhall b/dhall-lang/Prelude/Text/spaces.dhall
--- a/dhall-lang/Prelude/Text/spaces.dhall
+++ b/dhall-lang/Prelude/Text/spaces.dhall
@@ -6,8 +6,8 @@
 -}
 
 let replicate =
-        ./replicate sha256:1b398b1d464b3a6c7264a690ac3cacb443b5683b43348c859d68e7c2cb925c4f
-      ? ./replicate
+        ./replicate.dhall sha256:1b398b1d464b3a6c7264a690ac3cacb443b5683b43348c859d68e7c2cb925c4f
+      ? ./replicate.dhall
 
 let spaces
     : Natural → Text
diff --git a/dhall-lang/Prelude/XML/element.dhall b/dhall-lang/Prelude/XML/element.dhall
--- a/dhall-lang/Prelude/XML/element.dhall
+++ b/dhall-lang/Prelude/XML/element.dhall
@@ -21,12 +21,12 @@
 
 
 let XML =
-        ./Type sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c
-      ? ./Type
+        ./Type.dhall sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c
+      ? ./Type.dhall
 
 let List/map =
-        ../List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
-      ? ../List/map
+        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
+      ? ../List/map.dhall
 
 let Args =
         { attributes : List { mapKey : Text, mapValue : Text }
diff --git a/dhall-lang/Prelude/XML/leaf.dhall b/dhall-lang/Prelude/XML/leaf.dhall
--- a/dhall-lang/Prelude/XML/leaf.dhall
+++ b/dhall-lang/Prelude/XML/leaf.dhall
@@ -11,12 +11,12 @@
 -}
 
 let XML =
-        ./Type sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c
-      ? ./Type
+        ./Type.dhall sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c
+      ? ./Type.dhall
 
 let element =
-        ./element sha256:e0b948053c8cd8ccca9c39244d89e3f42db43d222531c18151551dfc75208b4b
-      ? ./element
+        ./element.dhall sha256:e0b948053c8cd8ccca9c39244d89e3f42db43d222531c18151551dfc75208b4b
+      ? ./element.dhall
 
 let leaf
     : { attributes : List { mapKey : Text, mapValue : Text }, name : Text } →
diff --git a/dhall-lang/Prelude/XML/package.dhall b/dhall-lang/Prelude/XML/package.dhall
--- a/dhall-lang/Prelude/XML/package.dhall
+++ b/dhall-lang/Prelude/XML/package.dhall
@@ -1,22 +1,22 @@
 { Type =
-      ./Type sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c
-    ? ./Type
+      ./Type.dhall sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c
+    ? ./Type.dhall
 , attribute =
-      ./attribute sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc
-    ? ./attribute
+      ./attribute.dhall sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc
+    ? ./attribute.dhall
 , render =
-      ./render sha256:8d034f7f97cded14a96147565d489be840e5678480d175b962b2600d85a3230e
-    ? ./render
+      ./render.dhall sha256:8d034f7f97cded14a96147565d489be840e5678480d175b962b2600d85a3230e
+    ? ./render.dhall
 , element =
-      ./element sha256:e0b948053c8cd8ccca9c39244d89e3f42db43d222531c18151551dfc75208b4b
-    ? ./element
+      ./element.dhall sha256:e0b948053c8cd8ccca9c39244d89e3f42db43d222531c18151551dfc75208b4b
+    ? ./element.dhall
 , leaf =
-      ./leaf sha256:4383e4fc4bf6a29ac2052776972eb59d5355a1cd067cded80d4ff32840969261
-    ? ./leaf
+      ./leaf.dhall sha256:4383e4fc4bf6a29ac2052776972eb59d5355a1cd067cded80d4ff32840969261
+    ? ./leaf.dhall
 , text =
-      ./text sha256:c83cd721d32d7dc28c04ce429c0cb22812639e572637ec348578a58ffb68844f
-    ? ./text
+      ./text.dhall sha256:c83cd721d32d7dc28c04ce429c0cb22812639e572637ec348578a58ffb68844f
+    ? ./text.dhall
 , emptyAttributes =
-      ./emptyAttributes sha256:11b86e2d3f3c75d47a1d580213d2a03fd2c36d64f3e9b6381de0ba23472f64d5
-    ? ./emptyAttributes
+      ./emptyAttributes.dhall sha256:11b86e2d3f3c75d47a1d580213d2a03fd2c36d64f3e9b6381de0ba23472f64d5
+    ? ./emptyAttributes.dhall
 }
diff --git a/dhall-lang/Prelude/XML/render.dhall b/dhall-lang/Prelude/XML/render.dhall
--- a/dhall-lang/Prelude/XML/render.dhall
+++ b/dhall-lang/Prelude/XML/render.dhall
@@ -24,16 +24,16 @@
 -}
 
 let XML =
-        ./Type sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c
-      ? ./Type
+        ./Type.dhall sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c
+      ? ./Type.dhall
 
 let Text/concatMap =
-        ../Text/concatMap sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f
-      ? ../Text/concatMap
+        ../Text/concatMap.dhall sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f
+      ? ../Text/concatMap.dhall
 
 let Text/concat =
-        ../Text/concat sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0
-      ? ../Text/concat
+        ../Text/concat.dhall sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0
+      ? ../Text/concat.dhall
 
 let Attr = { mapKey : Text, mapValue : Text }
 
diff --git a/dhall-lang/Prelude/XML/text.dhall b/dhall-lang/Prelude/XML/text.dhall
--- a/dhall-lang/Prelude/XML/text.dhall
+++ b/dhall-lang/Prelude/XML/text.dhall
@@ -16,8 +16,8 @@
 -}
 
 let XML =
-        ./Type sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c
-      ? ./Type
+        ./Type.dhall sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c
+      ? ./Type.dhall
 
 let text
     : Text → XML
diff --git a/dhall-lang/Prelude/package.dhall b/dhall-lang/Prelude/package.dhall
--- a/dhall-lang/Prelude/package.dhall
+++ b/dhall-lang/Prelude/package.dhall
@@ -17,11 +17,11 @@
       ./Location/package.dhall sha256:0eb4e4a60814018009c720f6820aaa13cf9491eb1b09afb7b832039c6ee4d470
     ? ./Location/package.dhall
 , Map =
-      ./Map/package.dhall sha256:598e9c76103b2686fbbda6cc30078f9e60dd846d9eaf155d0149cf0ae06c21c5
+      ./Map/package.dhall sha256:c6602939eb75ddaf43e75a37e1f27ace97e03685ceb9d77605b4372547f7cfa8
     ? ./Map/package.dhall
 , Monoid =
-      ./Monoid sha256:26fafa098600ef7a54ef9dba5ada416bbbdd21df1af306c052420c61553ad4af
-    ? ./Monoid
+      ./Monoid.dhall sha256:26fafa098600ef7a54ef9dba5ada416bbbdd21df1af306c052420c61553ad4af
+    ? ./Monoid.dhall
 , Natural =
       ./Natural/package.dhall sha256:ee9ed2b28a417ed4e9a0c284801b928bf91b3fbdc1a68616347678c1821f1ddf
     ? ./Natural/package.dhall
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceAbstractA.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceAbstractA.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceAbstractA.dhall
@@ -0,0 +1,4 @@
+{- This test verifies that an implementation correctly permits both the
+   "replacement" and the "haystack" to be abstract.
+-}
+λ(x : Text) → λ(y : Text) → Text/replace "a" "-${x}-" "_a_${y}_a_"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceAbstractB.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceAbstractB.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceAbstractB.dhall
@@ -0,0 +1,1 @@
+λ(x : Text) → λ(y : Text) → "_-${x}-_${y}_-${x}-_"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceEmptyA.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceEmptyA.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceEmptyA.dhall
@@ -0,0 +1,1 @@
+Text/replace "" "bar" "foo"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceEmptyB.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceEmptyB.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceEmptyB.dhall
@@ -0,0 +1,1 @@
+"foo"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceMultipleA.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceMultipleA.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceMultipleA.dhall
@@ -0,0 +1,1 @@
+Text/replace "foo" "bar" "foobazfoo"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceMultipleB.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceMultipleB.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceMultipleB.dhall
@@ -0,0 +1,1 @@
+"barbazbar"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceNFCUnicodeA.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceNFCUnicodeA.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceNFCUnicodeA.dhall
@@ -0,0 +1,1 @@
+Text/replace "👨" "👩" "👨‍👩‍👧‍👦"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceNFCUnicodeB.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceNFCUnicodeB.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceNFCUnicodeB.dhall
@@ -0,0 +1,1 @@
+"👩‍👩‍👧‍👦"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceNormalizationA.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceNormalizationA.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceNormalizationA.dhall
@@ -0,0 +1,3 @@
+-- This test verifies that implementations do not perform Unicode normalization
+-- before substitution.
+Text/replace "a\u{0301}" "b" "\u{00e1}c"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceNormalizationB.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceNormalizationB.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceNormalizationB.dhall
@@ -0,0 +1,1 @@
+"ác"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceSimpleA.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceSimpleA.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceSimpleA.dhall
@@ -0,0 +1,1 @@
+Text/replace "foo" "bar" "foo"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceSimpleB.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceSimpleB.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceSimpleB.dhall
@@ -0,0 +1,1 @@
+"bar"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceUnicodeA.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceUnicodeA.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceUnicodeA.dhall
@@ -0,0 +1,1 @@
+Text/replace "💣" "💥" "💣💣💣"
diff --git a/dhall-lang/tests/normalization/success/unit/TextReplaceUnicodeB.dhall b/dhall-lang/tests/normalization/success/unit/TextReplaceUnicodeB.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/TextReplaceUnicodeB.dhall
@@ -0,0 +1,1 @@
+"💥💥💥"
diff --git a/dhall-lang/tests/normalization/success/unit/WithCreateIntermediateRecordsA.dhall b/dhall-lang/tests/normalization/success/unit/WithCreateIntermediateRecordsA.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/WithCreateIntermediateRecordsA.dhall
@@ -0,0 +1,3 @@
+{- This test illustrates that if an intermediate record does
+   not exist, the `with` operator can create one -}
+{ a = 5 } with b.c = 10
diff --git a/dhall-lang/tests/normalization/success/unit/WithCreateIntermediateRecordsB.dhall b/dhall-lang/tests/normalization/success/unit/WithCreateIntermediateRecordsB.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/WithCreateIntermediateRecordsB.dhall
@@ -0,0 +1,1 @@
+{ a = 5, b.c = 10 }
diff --git a/dhall-lang/tests/normalization/success/unit/WithDesugarA.dhall b/dhall-lang/tests/normalization/success/unit/WithDesugarA.dhall
--- a/dhall-lang/tests/normalization/success/unit/WithDesugarA.dhall
+++ b/dhall-lang/tests/normalization/success/unit/WithDesugarA.dhall
@@ -1,4 +1,3 @@
-{- This test verifies that an implementation desugars `with` correctly by
-   leaving `x` abstract
+{- This test verifies that an implementation no longer implements the old desugaring (pre-v19.0.0)
 -}
 \(x: { a : { b : { c : {} } }}) -> x with a.b.c = 42
diff --git a/dhall-lang/tests/normalization/success/unit/WithDesugarB.dhall b/dhall-lang/tests/normalization/success/unit/WithDesugarB.dhall
--- a/dhall-lang/tests/normalization/success/unit/WithDesugarB.dhall
+++ b/dhall-lang/tests/normalization/success/unit/WithDesugarB.dhall
@@ -1,1 +1,1 @@
-λ(x : { a : { b : { c : {} } } }) → x ⫽ { a = x.a ⫽ { b = x.a.b ⫽ { c = 42 } } }
+λ(x : { a : { b : { c : {} } } }) → x with a.b.c = 42
diff --git a/dhall-lang/tests/normalization/success/unit/WithPartiallyAbstractA.dhall b/dhall-lang/tests/normalization/success/unit/WithPartiallyAbstractA.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/WithPartiallyAbstractA.dhall
@@ -0,0 +1,4 @@
+{- This test verifies that an implementation will evaluate a
+partially abstract `with` expression correctly
+-}
+λ(x : { b : { c : {} } }) → { a = x } with a.b.c = 42
diff --git a/dhall-lang/tests/normalization/success/unit/WithPartiallyAbstractB.dhall b/dhall-lang/tests/normalization/success/unit/WithPartiallyAbstractB.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/normalization/success/unit/WithPartiallyAbstractB.dhall
@@ -0,0 +1,1 @@
+λ(x : { b : { c : {} } }) → { a = x with b.c = 42 }
diff --git a/dhall-lang/tests/normalization/success/unit/WithUnderscoreA.dhall b/dhall-lang/tests/normalization/success/unit/WithUnderscoreA.dhall
deleted file mode 100644
--- a/dhall-lang/tests/normalization/success/unit/WithUnderscoreA.dhall
+++ /dev/null
@@ -1,5 +0,0 @@
-{- This test checks that an implementation doesn't mistakenly implement the
-   optimization suggested by the standard without the requisite shift
-   judgment
--}
-let _ = 1 in {=} with a = _
diff --git a/dhall-lang/tests/normalization/success/unit/WithUnderscoreB.dhall b/dhall-lang/tests/normalization/success/unit/WithUnderscoreB.dhall
deleted file mode 100644
--- a/dhall-lang/tests/normalization/success/unit/WithUnderscoreB.dhall
+++ /dev/null
@@ -1,1 +0,0 @@
-{ a = 1 }
diff --git a/dhall-lang/tests/parser/success/builtinsA.dhall b/dhall-lang/tests/parser/success/builtinsA.dhall
--- a/dhall-lang/tests/parser/success/builtinsA.dhall
+++ b/dhall-lang/tests/parser/success/builtinsA.dhall
@@ -19,6 +19,7 @@
 , List/indexed
 , List/reverse
 , Text/show
+, Text/replace
 , Bool
 , True
 , False
diff --git a/dhall-lang/tests/parser/success/builtinsB.dhallb b/dhall-lang/tests/parser/success/builtinsB.dhallb
--- a/dhall-lang/tests/parser/success/builtinsB.dhallb
+++ b/dhall-lang/tests/parser/success/builtinsB.dhallb
@@ -1,1 +1,1 @@
-$ölNatural/foldmNatural/buildnNatural/isZerolNatural/evenkNatural/oddqNatural/toIntegerlNatural/showpInteger/toDoublelInteger/shownInteger/negatemInteger/clamppNatural/subtractkDouble/showjList/buildiList/foldkList/lengthiList/headiList/lastlList/indexedlList/reverseiText/showdBoolõôhOptionaldNonegNaturalgIntegerfDoubledTextdListdTypedKinddSort
+%ölNatural/foldmNatural/buildnNatural/isZerolNatural/evenkNatural/oddqNatural/toIntegerlNatural/showpInteger/toDoublelInteger/shownInteger/negatemInteger/clamppNatural/subtractkDouble/showjList/buildiList/foldkList/lengthiList/headiList/lastlList/indexedlList/reverseiText/showlText/replacedBoolõôhOptionaldNonegNaturalgIntegerfDoubledTextdListdTypedKinddSort
diff --git a/dhall-lang/tests/type-inference/success/preludeB.dhall b/dhall-lang/tests/type-inference/success/preludeB.dhall
--- a/dhall-lang/tests/type-inference/success/preludeB.dhall
+++ b/dhall-lang/tests/type-inference/success/preludeB.dhall
@@ -361,6 +361,11 @@
         ∀(f : a → b) →
         ∀(m : List { mapKey : k, mapValue : a }) →
           List { mapKey : k, mapValue : b }
+    , unpackOptionals :
+        ∀(k : Type) →
+        ∀(v : Type) →
+        ∀(xs : List { mapKey : k, mapValue : Optional v }) →
+          List { mapKey : k, mapValue : v }
     , values :
         ∀(k : Type) →
         ∀(v : Type) →
diff --git a/dhall-lang/tests/type-inference/success/unit/TextReplaceA.dhall b/dhall-lang/tests/type-inference/success/unit/TextReplaceA.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextReplaceA.dhall
@@ -0,0 +1,1 @@
+Text/replace
diff --git a/dhall-lang/tests/type-inference/success/unit/TextReplaceB.dhall b/dhall-lang/tests/type-inference/success/unit/TextReplaceB.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/TextReplaceB.dhall
@@ -0,0 +1,1 @@
+∀(needle : Text) → ∀(replacement : Text) → ∀(haystack : Text) → Text
diff --git a/dhall-lang/tests/type-inference/success/unit/WithCreateIntermediateRecordsA.dhall b/dhall-lang/tests/type-inference/success/unit/WithCreateIntermediateRecordsA.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/WithCreateIntermediateRecordsA.dhall
@@ -0,0 +1,3 @@
+{- This test illustrates that if an intermediate record does
+   not exist, the `with` operator can create one -}
+{ a = 5 } with b.c = 10
diff --git a/dhall-lang/tests/type-inference/success/unit/WithCreateIntermediateRecordsB.dhall b/dhall-lang/tests/type-inference/success/unit/WithCreateIntermediateRecordsB.dhall
new file mode 100644
--- /dev/null
+++ b/dhall-lang/tests/type-inference/success/unit/WithCreateIntermediateRecordsB.dhall
@@ -0,0 +1,1 @@
+{ a : Natural, b : { c : Natural } }
diff --git a/dhall.cabal b/dhall.cabal
--- a/dhall.cabal
+++ b/dhall.cabal
@@ -1,5 +1,5 @@
 Name: dhall
-Version: 1.35.0
+Version: 1.36.0
 Cabal-Version: >=1.10
 Build-Type: Simple
 Tested-With: GHC == 8.4.3, GHC == 8.6.1
@@ -502,8 +502,8 @@
         parser-combinators                               ,
         prettyprinter               >= 1.5.1    && < 1.8 ,
         prettyprinter-ansi-terminal >= 1.1.1    && < 1.2 ,
-        pretty-simple                              < 4   ,
-        profunctors                 >= 3.1.2    && < 5.6 ,
+        pretty-simple                              < 4.1 ,
+        profunctors                 >= 3.1.2    && < 5.7 ,
         repline                     >= 0.4.0.0  && < 0.5 ,
         serialise                   >= 0.2.0.0  && < 0.3 ,
         scientific                  >= 0.3.0.0  && < 0.4 ,
@@ -665,6 +665,8 @@
         filepath                                       ,
         foldl                                    < 1.5 ,
         generic-random            >= 1.3.0.0  && < 1.4 ,
+        http-client                                    ,
+        http-client-tls                                ,
         lens-family-core                               ,
         megaparsec                                     ,
         prettyprinter                                  ,
diff --git a/src/Dhall/Binary.hs b/src/Dhall/Binary.hs
--- a/src/Dhall/Binary.hs
+++ b/src/Dhall/Binary.hs
@@ -192,6 +192,7 @@
                        | sb == "Natural/even"      -> return NaturalEven
                        | sb == "Natural/fold"      -> return NaturalFold
                        | sb == "Natural/show"      -> return NaturalShow
+                       | sb == "Text/replace"      -> return TextReplace
                     13 | sb == "Integer/clamp"     -> return IntegerClamp
                        | sb == "Natural/build"     -> return NaturalBuild
                     14 | sb == "Integer/negate"    -> return IntegerNegate
@@ -701,6 +702,9 @@
 
         Text ->
             Encoding.encodeUtf8ByteArray "Text"
+
+        TextReplace ->
+            Encoding.encodeUtf8ByteArray "Text/replace"
 
         TextShow ->
             Encoding.encodeUtf8ByteArray "Text/show"
diff --git a/src/Dhall/Diff.hs b/src/Dhall/Diff.hs
--- a/src/Dhall/Diff.hs
+++ b/src/Dhall/Diff.hs
@@ -1032,8 +1032,29 @@
     diffWithExpression l r
 
 diffWithExpression :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff
-diffWithExpression l@With{} r@With{} =
-    diffWithExpression (Syntax.desugarWith l) (Syntax.desugarWith r)
+diffWithExpression (With eL ksL vL) (With eR ksR vR) =
+    align
+        (   format " " (diffImportExpression eL eR)
+        <>  "with "
+        <>  align
+            (   format " " (diffPath ksL ksR)
+            <>  "= "
+            <>  diffOperatorExpression vL vR
+            )
+        )
+  where
+    diffPath (kL :| []) (kR :| []) =
+        diffLabel kL kR
+    diffPath (kL₀ :| kL₁ : ksL') (kR₀ :| kR₁ : ksR') =
+            format "" (diffLabel kL₀ kR₀)
+        <>  dot
+        <>  diffPath (kL₁ :| ksL') (kR₁ :| ksR')
+    diffPath (kL :| []) (kR₀ :| kR₁ : ksR') =
+            format "" (diffLabel kL kR₀)
+        <>  plus (foldMap (\k -> dot <> token (Internal.prettyLabel k)) (kR₁ :| ksR'))
+    diffPath (kL₀ :| kL₁ : ksL') (kR :| []) =
+            format "" (diffLabel kL₀ kR)
+        <>  minus (foldMap (\k -> dot <> token (Internal.prettyLabel k)) (kL₁ :| ksL'))
 diffWithExpression l r@With{} =
     mismatch l r
 diffWithExpression l@With{} r =
@@ -1215,6 +1236,12 @@
 diffPrimitiveExpression l@Text r =
     mismatch l r
 diffPrimitiveExpression l r@Text =
+    mismatch l r
+diffPrimitiveExpression TextReplace TextReplace =
+    "…"
+diffPrimitiveExpression l@TextReplace r =
+    mismatch l r
+diffPrimitiveExpression l r@TextReplace =
     mismatch l r
 diffPrimitiveExpression TextShow TextShow =
     "…"
diff --git a/src/Dhall/Eval.hs b/src/Dhall/Eval.hs
--- a/src/Dhall/Eval.hs
+++ b/src/Dhall/Eval.hs
@@ -50,14 +50,15 @@
   , textShow
   ) where
 
-import Data.Foldable (foldr', toList)
-import Data.Sequence (Seq, ViewL (..), ViewR (..))
-import Data.Text     (Text)
-import Data.Void     (Void)
-import Dhall.Map     (Map)
-import Dhall.Set     (Set)
-import GHC.Natural   (Natural)
-import Prelude       hiding (succ)
+import Data.Foldable      (foldr', toList)
+import Data.List.NonEmpty (NonEmpty(..))
+import Data.Sequence      (Seq, ViewL (..), ViewR (..))
+import Data.Text          (Text)
+import Data.Void          (Void)
+import Dhall.Map          (Map)
+import Dhall.Set          (Set)
+import GHC.Natural        (Natural)
+import Prelude            hiding (succ)
 
 import Dhall.Syntax
     ( Binding (..)
@@ -191,6 +192,7 @@
     | VTextLit !(VChunks a)
     | VTextAppend !(Val a) !(Val a)
     | VTextShow !(Val a)
+    | VTextReplace !(Val a) !(Val a) !(Val a)
 
     | VList !(Val a)
     | VListLit !(Maybe (Val a)) !(Seq (Val a))
@@ -219,6 +221,7 @@
     | VProject !(Val a) !(Either (Set Text) (Val a))
     | VAssert !(Val a)
     | VEquivalent !(Val a) !(Val a)
+    | VWith !(Val a) (NonEmpty Text) !(Val a)
     | VEmbed a
 
 -- | For use with "Text.Show.Functions".
@@ -360,6 +363,54 @@
     singletonVRecordLit v = VRecordLit (Map.singleton k v)
 {-# INLINE vField #-}
 
+vTextReplaceSlow :: Text -> Val a -> VChunks a -> VChunks a
+vTextReplaceSlow needle replacement haystack = go haystack
+  where
+    go (VChunks [] lastText) =
+        if Text.null suffix
+        then VChunks [] lastText
+        else
+            let remainder = Text.drop (Text.length needle) suffix
+
+                rest = go (VChunks [] remainder)
+
+            in  case replacement of
+                    VTextLit replacementChunks ->
+                        VChunks [] prefix <> replacementChunks <> rest
+                    _ ->
+                        VChunks [(prefix, replacement)] "" <> rest
+      where
+        (prefix, suffix) = Text.breakOn needle lastText
+    go (VChunks ((firstText, firstInterpolation) : chunks) lastText) =
+       if Text.null suffix
+       then
+           let rest = go (VChunks chunks lastText)
+
+           in  VChunks [(firstText, firstInterpolation)] "" <> rest
+       else
+           let remainder = Text.drop (Text.length needle) suffix
+
+               rest =
+                   go (VChunks ((remainder, firstInterpolation) : chunks) lastText)
+
+           in  case replacement of
+                   VTextLit replacementChunks ->
+                       VChunks [] prefix <> replacementChunks <> rest
+                   _ ->
+                       VChunks [(prefix, replacement)] "" <> rest
+      where
+        (prefix, suffix) = Text.breakOn needle firstText
+
+vTextReplaceFast :: Text -> Text -> VChunks a -> VChunks a
+vTextReplaceFast needle replacement (VChunks xys z) = VChunks xys' z'
+  where
+    xys' = do
+       (x, y) <- xys
+
+       return (Text.replace needle replacement x, y)
+
+    z' = Text.replace needle replacement z
+
 vProjectByFields :: Eq a => Environment a -> Val a -> Set Text -> Val a
 vProjectByFields env t ks =
     if null ks
@@ -383,6 +434,18 @@
             t' ->
                 VProject t' (Left ks)
 
+vWith :: Val a -> NonEmpty Text -> Val a -> Val a
+vWith (VRecordLit kvs) (k  :| []     ) v = VRecordLit (Map.insert k  v  kvs)
+vWith (VRecordLit kvs) (k₀ :| k₁ : ks) v = VRecordLit (Map.insert k₀ e₂ kvs)
+  where
+    e₁ =
+        case Map.lookup k₀ kvs of
+            Nothing  -> VRecordLit mempty
+            Just e₁' -> e₁'
+
+    e₂ = vWith e₁ (k₁ :| ks) v
+vWith e₀ ks v₀ = VWith e₀ ks v₀
+
 eval :: forall a. Eq a => Environment a -> Expr Void a -> Val a
 eval !env t0 =
     case t0 of
@@ -566,6 +629,35 @@
             VPrim $ \case
                 VTextLit (VChunks [] x) -> VTextLit (VChunks [] (textShow x))
                 t                       -> VTextShow t
+        TextReplace ->
+            VPrim $ \needle ->
+            VPrim $ \replacement ->
+            VPrim $ \haystack ->
+                case haystack of
+                    VTextLit haystackChunks ->
+                        case needle of
+                            VTextLit (VChunks [] "") ->
+                                haystack
+                            VTextLit (VChunks [] needleText) ->
+                                case replacement of
+                                    VTextLit (VChunks [] replacementText) ->
+                                        VTextLit
+                                            (vTextReplaceFast
+                                                needleText
+                                                replacementText
+                                                haystackChunks
+                                            )
+                                    _ ->
+                                        VTextLit
+                                            (vTextReplaceSlow
+                                                needleText
+                                                replacement
+                                                haystackChunks
+                                            )
+                            _ ->
+                                VTextReplace needle replacement haystack
+                    _ ->
+                        VTextReplace needle replacement haystack
         List ->
             VPrim VList
         ListLit ma ts ->
@@ -725,8 +817,8 @@
             VAssert (eval env t)
         Equivalent t u ->
             VEquivalent (eval env t) (eval env u)
-        e@With{} ->
-            eval env (Syntax.desugarWith e)
+        With e₀ ks v ->
+            vWith (eval env e₀) ks (eval env v)
         Note _ e ->
             eval env e
         ImportAlt t _ ->
@@ -881,6 +973,8 @@
             conv env t t' && conv env u u'
         (VTextShow t, VTextShow t') ->
             conv env t t'
+        (VTextReplace a b c, VTextReplace a' b' c') ->
+            conv env a a' && conv env b b' && conv env c c'
         (VList a, VList a') ->
             conv env a a'
         (VListLit _ xs, VListLit _ xs') ->
@@ -1068,6 +1162,8 @@
             TextAppend (quote env t) (quote env u)
         VTextShow t ->
             TextShow `qApp` t
+        VTextReplace a b c ->
+            TextReplace `qApp` a `qApp` b `qApp` c
         VList t ->
             List `qApp` t
         VListLit ma ts ->
@@ -1118,6 +1214,8 @@
             Assert (quote env t)
         VEquivalent t u ->
             Equivalent (quote env t) (quote env u)
+        VWith e ks v ->
+            With (quote env e) ks (quote env v)
         VInject m k Nothing ->
             Field (Union (fmap (fmap (quote env)) m)) $ Syntax.makeFieldSelection k
         VInject m k (Just t) ->
@@ -1248,6 +1346,8 @@
                 TextAppend (go t) (go u)
             TextShow ->
                 TextShow
+            TextReplace ->
+                TextReplace
             List ->
                 List
             ListLit ma ts ->
diff --git a/src/Dhall/Lint.hs b/src/Dhall/Lint.hs
--- a/src/Dhall/Lint.hs
+++ b/src/Dhall/Lint.hs
@@ -13,6 +13,7 @@
     , removeUnusedBindings
     , fixAssert
     , fixParentPath
+    , addPreludeExtensions
     , removeLetInLet
     , useToMap
     ) where
@@ -29,12 +30,14 @@
     , Import (..)
     , ImportHashed (..)
     , ImportType (..)
+    , URL (..)
     , Var (..)
     , subExpressions
     )
 
 import qualified Data.Foldable      as Foldable
 import qualified Data.List.NonEmpty as NonEmpty
+import qualified Data.Text          as Text
 import qualified Dhall.Core         as Core
 import qualified Dhall.Map          as Map
 import qualified Dhall.Optics
@@ -57,6 +60,7 @@
         <|> removeUnusedBindings     e
         <|> fixParentPath            e
         <|> removeLetInLet           e
+        <|> addPreludeExtensions     e
 
 -- | Remove unused `Let` bindings.
 removeUnusedBindings :: Eq a => Expr s a -> Maybe (Expr s a)
@@ -103,6 +107,40 @@
         _ ->
             Nothing
 fixParentPath _  = Nothing
+
+{-| This transforms @https://prelude.dhall-lang.org/…/foo@ to
+    @https://prelude.dhall-lang.org/…/foo.dhall@
+-}
+addPreludeExtensions :: Expr s Import -> Maybe (Expr s Import)
+addPreludeExtensions (Embed oldImport) = do
+    let Import{ importHashed = oldImportHashed, .. } = oldImport
+
+    let ImportHashed{ importType = oldImportType, .. } = oldImportHashed
+
+    case oldImportType of
+        Remote URL{ path = oldPath, ..}
+            | authority == "prelude.dhall-lang.org" ->
+                case oldPath of
+                    File{ file = oldFile, .. }
+                        | not (Text.isSuffixOf ".dhall" oldFile) -> do
+                            let newFile = oldFile <> ".dhall"
+
+                            let newPath = File{ file = newFile, .. }
+
+                            let newImportType = Remote URL{ path = newPath, .. }
+
+                            let newImportHashed =
+                                    ImportHashed{ importType = newImportType, .. }
+
+                            let newImport =
+                                    Import{ importHashed = newImportHashed, .. }
+
+                            return (Embed newImport)
+                    _ ->
+                        Nothing
+        _ -> do
+            Nothing
+addPreludeExtensions _ = Nothing
 
 isOrContainsAssert :: Expr s a -> Bool
 isOrContainsAssert (Assert _) = True
diff --git a/src/Dhall/Main.hs b/src/Dhall/Main.hs
--- a/src/Dhall/Main.hs
+++ b/src/Dhall/Main.hs
@@ -339,6 +339,7 @@
                 (   Options.Applicative.long "file"
                 <>  Options.Applicative.help "Read expression from a file instead of standard input"
                 <>  Options.Applicative.metavar "FILE"
+                <>  Options.Applicative.action "file"
                 )
 
     parseOutput = fmap f (optional p)
@@ -350,6 +351,7 @@
                 (   Options.Applicative.long "output"
                 <>  Options.Applicative.help "Write result to a file instead of standard output"
                 <>  Options.Applicative.metavar "FILE"
+                <>  Options.Applicative.action "file"
                 )
 
     parseAlpha =
@@ -410,6 +412,7 @@
             (   Options.Applicative.long "inplace"
             <>  Options.Applicative.help "Modify the specified file in-place"
             <>  Options.Applicative.metavar "FILE"
+            <>  Options.Applicative.action "file"
             )
 
     parseInplaceNonTransitive =
@@ -425,6 +428,7 @@
             (   Options.Applicative.long "transitive"
             <>  Options.Applicative.help "Modify the specified file and its transitive relative imports in-place"
             <>  Options.Applicative.metavar "FILE"
+            <>  Options.Applicative.action "file"
             )
 
     parseInput = fmap f (optional p)
@@ -436,6 +440,8 @@
             (   Options.Applicative.long "path"
             <>  Options.Applicative.help "Index all files in path recursively. Will get list of files from STDIN if omitted."
             <>  Options.Applicative.metavar "PATH"
+            <>  Options.Applicative.action "file"
+            <>  Options.Applicative.action "directory"
             )
 
     parseTagsOutput = fmap f (optional p)
@@ -447,6 +453,7 @@
             (   Options.Applicative.long "output"
             <>  Options.Applicative.help "The name of the file that the tags are written to. Defaults to \"tags\""
             <>  Options.Applicative.metavar "FILENAME"
+            <>  Options.Applicative.action "file"
             )
 
     parseSuffixes = fmap f (optional p)
@@ -508,6 +515,7 @@
             (   Options.Applicative.long "output"
             <>  Options.Applicative.help "The destination path to create"
             <>  Options.Applicative.metavar "PATH"
+            <>  Options.Applicative.action "directory"
             )
 
     parseNoted =
diff --git a/src/Dhall/Normalize.hs b/src/Dhall/Normalize.hs
--- a/src/Dhall/Normalize.hs
+++ b/src/Dhall/Normalize.hs
@@ -23,6 +23,7 @@
 import Control.Applicative   (empty)
 import Data.Foldable
 import Data.Functor.Identity (Identity (..))
+import Data.List.NonEmpty    (NonEmpty(..))
 import Data.Sequence         (ViewL (..), ViewR (..))
 import Data.Traversable
 import Instances.TH.Lift     ()
@@ -42,7 +43,7 @@
 
 import qualified Data.Sequence
 import qualified Data.Set
-import qualified Data.Text
+import qualified Data.Text     as Text
 import qualified Dhall.Eval    as Eval
 import qualified Dhall.Map
 import qualified Dhall.Set
@@ -226,7 +227,7 @@
                     App NaturalOdd (NaturalLit n) -> pure (BoolLit (odd n))
                     App NaturalToInteger (NaturalLit n) -> pure (IntegerLit (toInteger n))
                     App NaturalShow (NaturalLit n) ->
-                        pure (TextLit (Chunks [] (Data.Text.pack (show n))))
+                        pure (TextLit (Chunks [] (Text.pack (show n))))
                     App (App NaturalSubtract (NaturalLit x)) (NaturalLit y)
                         -- Use an `Integer` for the subtraction, due to the
                         -- following issue:
@@ -245,14 +246,14 @@
                     App IntegerNegate (IntegerLit n) ->
                         pure (IntegerLit (negate n))
                     App IntegerShow (IntegerLit n)
-                        | 0 <= n    -> pure (TextLit (Chunks [] ("+" <> Data.Text.pack (show n))))
-                        | otherwise -> pure (TextLit (Chunks [] (Data.Text.pack (show n))))
+                        | 0 <= n    -> pure (TextLit (Chunks [] ("+" <> Text.pack (show n))))
+                        | otherwise -> pure (TextLit (Chunks [] (Text.pack (show n))))
                     -- `(read . show)` is used instead of `fromInteger` because `read` uses
                     -- the correct rounding rule.
                     -- See https://gitlab.haskell.org/ghc/ghc/issues/17231.
                     App IntegerToDouble (IntegerLit n) -> pure (DoubleLit ((DhallDouble . read . show) n))
                     App DoubleShow (DoubleLit (DhallDouble n)) ->
-                        pure (TextLit (Chunks [] (Data.Text.pack (show n))))
+                        pure (TextLit (Chunks [] (Text.pack (show n))))
                     App (App ListBuild _A₀) g -> loop (App (App (App g list) cons) nil)
                       where
                         _A₁ = Syntax.shift 1 "a" _A₀
@@ -317,6 +318,64 @@
                         loop (TextLit (Chunks [] newText))
                       where
                         newText = Eval.textShow oldText
+                    App
+                        (App (App TextReplace (TextLit (Chunks [] ""))) _)
+                        haystack ->
+                            return haystack
+                    App (App
+                            (App TextReplace (TextLit (Chunks [] needleText)))
+                            (TextLit (Chunks [] replacementText))
+                        )
+                        (TextLit (Chunks xys z)) -> do
+                            let xys' = do
+                                    (x, y) <- xys
+
+                                    let x' = Text.replace needleText replacementText x
+                                    return (x', y)
+
+                            let z' = Text.replace needleText replacementText z
+
+                            return (TextLit (Chunks xys' z'))
+                    App (App
+                            (App TextReplace (TextLit (Chunks [] needleText)))
+                            replacement
+                        )
+                        (TextLit (Chunks [] lastText)) -> do
+                            let (prefix, suffix) =
+                                    Text.breakOn needleText lastText
+
+                            if Text.null suffix
+                                then return (TextLit (Chunks [] lastText))
+                                else do
+                                    let remainder =
+                                            Text.drop
+                                                (Text.length needleText)
+                                                suffix
+
+                                    loop (TextAppend (TextLit (Chunks [(prefix, replacement)] "")) (App (App (App TextReplace (TextLit (Chunks [] needleText))) replacement) (TextLit (Chunks [] remainder))))
+                    App (App
+                            (App TextReplace (TextLit (Chunks [] needleText)))
+                            replacement
+                        )
+                        (TextLit
+                            (Chunks
+                                ((firstText, firstInterpolation) : chunks)
+                                lastText
+                            )
+                        ) -> do
+                            let (prefix, suffix) =
+                                    Text.breakOn needleText firstText
+
+                            if Text.null suffix
+                                then do
+                                    loop (TextAppend (TextLit (Chunks [(firstText, firstInterpolation)] "")) (App (App (App TextReplace (TextLit (Chunks [] needleText))) replacement) (TextLit (Chunks chunks lastText))))
+                                else do
+                                    let remainder =
+                                            Text.drop
+                                                (Text.length needleText)
+                                                suffix
+
+                                    loop (TextAppend (TextLit (Chunks [(prefix, replacement)] "")) (App (App (App TextReplace (TextLit (Chunks [] needleText))) replacement) (TextLit (Chunks ((remainder, firstInterpolation) : chunks) lastText))))
                     _ -> do
                         res2 <- ctx (App f' a')
                         case res2 of
@@ -419,6 +478,7 @@
             TextLit c -> pure [Chunks [] x, c]
             _         -> pure [Chunks [(x, y')] mempty]
     TextAppend x y -> loop (TextLit (Chunks [("", x), ("", y)] ""))
+    TextReplace -> pure TextReplace
     TextShow -> pure TextShow
     List -> pure List
     ListLit t es
@@ -613,8 +673,26 @@
         r' <- loop r
 
         pure (Equivalent l' r')
-    With e' k v ->
-        loop (Syntax.desugarWith (With e' k v))
+    With e ks v -> do
+        e' <- loop e
+        v' <- loop v
+
+        case e' of
+            RecordLit kvs ->
+                case ks of
+                    k :| [] ->
+                        return (RecordLit (Dhall.Map.insert k (Syntax.makeRecordField v') kvs))
+                    k₀ :| k₁ : ks' -> do
+                        let e₁ =
+                                case Dhall.Map.lookup k₀ kvs of
+                                    Nothing -> RecordLit mempty
+                                    Just r  -> Syntax.recordFieldValue r
+
+                        e₂ <- loop (With e₁ (k₁ :| ks') v')
+
+                        return (RecordLit (Dhall.Map.insert k₀ (Syntax.makeRecordField e₂) kvs))
+            _ ->
+                return (With e' ks v')
     Note _ e' -> loop e'
     ImportAlt l _r -> loop l
     Embed a -> pure (Embed a)
@@ -684,6 +762,10 @@
           App (App ListReverse _) (ListLit _ _) -> False
           App TextShow (TextLit (Chunks [] _)) ->
               False
+          App (App (App TextReplace (TextLit (Chunks [] ""))) _) _ ->
+              False
+          App (App (App TextReplace (TextLit (Chunks [] _))) _) (TextLit _) ->
+              False
           _ -> True
       Let _ _ -> False
       Annot _ _ -> False
@@ -756,6 +838,7 @@
               TextLit _ -> False
               _         -> True
       TextAppend _ _ -> False
+      TextReplace -> True
       TextShow -> True
       List -> True
       ListLit t es -> all loop t && all loop es
diff --git a/src/Dhall/Parser.hs b/src/Dhall/Parser.hs
--- a/src/Dhall/Parser.hs
+++ b/src/Dhall/Parser.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE RecordWildCards   #-}
+{-# LANGUAGE OverloadedStrings #-}
 
 -- | This module contains Dhall's parsing logic
 
@@ -27,8 +28,7 @@
 import Dhall.Syntax
 import Text.Megaparsec   (ParseErrorBundle (..), PosState (..))
 
-import qualified Data.Char
-import qualified Data.Text
+import qualified Data.Text       as Text
 import qualified Dhall.Core      as Core
 import qualified Text.Megaparsec
 
@@ -76,7 +76,7 @@
 
 instance Exception ParseError
 
--- | Parse an expression from `Data.Text.Text` containing a Dhall program
+-- | Parse an expression from `Text.Text` containing a Dhall program
 exprFromText
   :: String -- ^ User-friendly name describing the input expression,
             --   used in parsing error messages
@@ -92,8 +92,15 @@
 
 -- | Create a header with stripped leading spaces and trailing newlines
 createHeader :: Text -> Header
-createHeader =
-    Header . Data.Text.dropWhile Data.Char.isSpace . Data.Text.dropWhileEnd (/= '\n')
+createHeader text = Header (prefix <> newSuffix)
+  where
+    isWhitespace c = c == ' ' || c == '\n' || c == '\r' || c == '\t'
+
+    prefix = Text.dropAround isWhitespace text
+
+    newSuffix
+        | Text.null prefix = ""
+        | otherwise        = "\n"
 
 -- | Like `exprFromText` but also returns the leading comments and whitespace
 -- (i.e. header) up to the last newline before the code begins
diff --git a/src/Dhall/Parser/Expression.hs b/src/Dhall/Parser/Expression.hs
--- a/src/Dhall/Parser/Expression.hs
+++ b/src/Dhall/Parser/Expression.hs
@@ -580,7 +580,8 @@
                     'S' ->    Const Sort       <$ _Sort
                     'T' ->
                         choice
-                            [ TextShow         <$ _TextShow
+                            [ TextReplace      <$ _TextReplace
+                            , TextShow         <$ _TextShow
                             , Text             <$ _Text
                             , BoolLit True     <$ _True
                             , Const Type       <$ _Type
@@ -874,10 +875,7 @@
                     _ <- optional (whitespace *> _comma)
 
                     whitespace
-                    {- The `flip` is necessary because `toMapWith` is internally
-                       based on `Data.Map.fromListWithKey` which combines keys
-                       in reverse order
-                    -}
+
                     let combine k = liftA2 $ \rf rf' -> makeRecordField $ Combine (Just k)
                                                             (recordFieldValue rf')
                                                             (recordFieldValue rf)
diff --git a/src/Dhall/Parser/Token.hs b/src/Dhall/Parser/Token.hs
--- a/src/Dhall/Parser/Token.hs
+++ b/src/Dhall/Parser/Token.hs
@@ -65,6 +65,7 @@
     _Integer,
     _Double,
     _Text,
+    _TextReplace,
     _TextShow,
     _List,
     _True,
@@ -1052,6 +1053,13 @@
 -}
 _Text :: Parser ()
 _Text = builtin "Text"
+
+{-| Parse the @Text/replace@ built-in
+
+    This corresponds to the @Text-replace@ rule from the official grammar
+-}
+_TextReplace :: Parser ()
+_TextReplace = builtin "Text/replace"
 
 {-| Parse the @Text/show@ built-in
 
diff --git a/src/Dhall/Pretty/Internal.hs b/src/Dhall/Pretty/Internal.hs
--- a/src/Dhall/Pretty/Internal.hs
+++ b/src/Dhall/Pretty/Internal.hs
@@ -765,8 +765,13 @@
                 docs d
             | otherwise =
                 [ prettyExpression c ]
-    prettyExpression (With a b c) =
-            prettyExpression a
+    prettyExpression (With (Dhall.Syntax.shallowDenote -> a) b c) =
+            case a of
+                With{} ->
+                    -- Don't parenthesize an inner with-expression
+                    prettyExpression a
+                _ ->
+                    prettyImportExpression_ a
         <>  Pretty.flatAlt long short
       where
         short = " " <> keyword "with" <> " " <> update
@@ -1253,6 +1258,8 @@
         builtin "Double/show"
     prettyPrimitiveExpression Text =
         builtin "Text"
+    prettyPrimitiveExpression TextReplace =
+        builtin "Text/replace"
     prettyPrimitiveExpression TextShow =
         builtin "Text/show"
     prettyPrimitiveExpression List =
@@ -1427,14 +1434,17 @@
     prettyCompletionLit :: Pretty a => Int -> Map Text (RecordField Src a) -> Doc Ann
     prettyCompletionLit = prettyRecordLike . hangingBraces
 
+    prettyRecordLike
+        :: Pretty a
+        => ([(Doc Ann, Doc Ann)] -> Doc Ann)
+        -> Map Text (RecordField Src a)
+        -> Doc Ann
     prettyRecordLike braceStyle a
         | Data.Foldable.null a =
             lbrace <> equals <> rbrace
         | otherwise =
-            braceStyle (map prettyRecordEntry consolidated)
+            braceStyle (map prettyRecordEntry (consolidateRecordLiteral a))
       where
-        consolidated = consolidateRecordLiteral a
-
         prettyRecordEntry kv@(KeyValue keys mSrc2 val) =
             case keys of
                 (mSrc0, key, mSrc1) :| []
@@ -1627,18 +1637,22 @@
 {- This utility function converts
    `{ x = { y = { z = 1 } } }` to `{ x.y.z = 1 }`
 -}
-consolidateRecordLiteral
-    :: Map Text (RecordField Src a) -> [KeyValue Src a]
-consolidateRecordLiteral = map adapt . Map.toList
+consolidateRecordLiteral :: Map Text (RecordField Src a) -> [KeyValue Src a]
+consolidateRecordLiteral = concatMap adapt . Map.toList
   where
-    adapt :: (Text, RecordField Src a) -> KeyValue Src a
+    adapt :: (Text, RecordField Src a) -> [KeyValue Src a]
     adapt (key, RecordField mSrc0 val mSrc1 mSrc2)
         | not (containsComment mSrc2)
-        , RecordLit m <- shallowDenote val
-        , [ KeyValue keys mSrc2' val' ] <- map adapt (Map.toList m) =
-            KeyValue (NonEmpty.cons (mSrc0, key, mSrc1) keys) mSrc2' val'
+        , RecordLit m <- e
+        , [ KeyValue keys mSrc2' val' ] <- concatMap adapt (Map.toList m) =
+            [ KeyValue (NonEmpty.cons (mSrc0, key, mSrc1) keys) mSrc2' val' ]
+
+        | Combine (Just _) l r <- e =
+            adapt (key, makeRecordField l) <> adapt (key, makeRecordField r)
         | otherwise =
-            KeyValue (pure (mSrc0, key, mSrc1)) mSrc2 val
+            [ KeyValue (pure (mSrc0, key, mSrc1)) mSrc2 val ]
+      where
+        e = shallowDenote val
 
 -- | Escape a `Data.Text.Text` literal using Dhall's escaping rules for
 --   single-quoted @Text@
diff --git a/src/Dhall/Syntax.hs b/src/Dhall/Syntax.hs
--- a/src/Dhall/Syntax.hs
+++ b/src/Dhall/Syntax.hs
@@ -506,9 +506,9 @@
     | Integer
     -- | > IntegerLit n                             ~  ±n
     | IntegerLit Integer
-    -- | > IntegerClamp                               ~  Integer/clamp
+    -- | > IntegerClamp                             ~  Integer/clamp
     | IntegerClamp
-    -- | > IntegerNegate                              ~  Integer/negate
+    -- | > IntegerNegate                            ~  Integer/negate
     | IntegerNegate
     -- | > IntegerShow                              ~  Integer/show
     | IntegerShow
@@ -526,6 +526,8 @@
     | TextLit (Chunks s a)
     -- | > TextAppend x y                           ~  x ++ y
     | TextAppend (Expr s a) (Expr s a)
+    -- | > TextReplace                              ~ Text/replace
+    | TextReplace
     -- | > TextShow                                 ~  Text/show
     | TextShow
     -- | > List                                     ~  List
@@ -809,6 +811,7 @@
 unsafeSubExpressions f (TextLit chunks) =
     TextLit <$> chunkExprs f chunks
 unsafeSubExpressions f (TextAppend a b) = TextAppend <$> f a <*> f b
+unsafeSubExpressions _ TextReplace = pure TextReplace
 unsafeSubExpressions _ TextShow = pure TextShow
 unsafeSubExpressions _ List = pure List
 unsafeSubExpressions f (ListLit a b) = ListLit <$> traverse f a <*> traverse f b
@@ -1202,6 +1205,7 @@
         , "List/last"
         , "List/indexed"
         , "List/reverse"
+        , "Text/replace"
         , "Text/show"
         , "Bool"
         , "True"
diff --git a/src/Dhall/TH.hs b/src/Dhall/TH.hs
--- a/src/Dhall/TH.hs
+++ b/src/Dhall/TH.hs
@@ -178,7 +178,7 @@
         Union kts -> do
             let name = Syntax.mkName (Text.unpack typeName)
 
-            constructors <- traverse (toConstructor haskellTypes) (Dhall.Map.toList kts )
+            constructors <- traverse (toConstructor haskellTypes typeName) (Dhall.Map.toList kts )
 
             return (DataD [] name [] Nothing constructors derivingClauses)
 
@@ -227,7 +227,7 @@
 toDeclaration haskellTypes SingleConstructor{..} = do
     let name = Syntax.mkName (Text.unpack typeName)
 
-    constructor <- toConstructor haskellTypes (constructorName, Just code)
+    constructor <- toConstructor haskellTypes typeName (constructorName, Just code)
 
     return (DataD [] name [] Nothing [constructor] derivingClauses)
 
@@ -235,15 +235,27 @@
 toConstructor
     :: (Eq a, Pretty a)
     => [HaskellType (Expr s a)]
+    -> Text
+    -- ^ typeName
     -> (Text, Maybe (Expr s a))
     -- ^ @(constructorName, fieldType)@
     -> Q Con
-toConstructor haskellTypes (constructorName, maybeAlternativeType) = do
+toConstructor haskellTypes outerTypeName (constructorName, maybeAlternativeType) = do
     let name = Syntax.mkName (Text.unpack constructorName)
 
     let bang = Bang NoSourceUnpackedness NoSourceStrictness
 
     case maybeAlternativeType of
+        Just dhallType
+            | let predicate haskellType =
+                    Core.judgmentallyEqual (code haskellType) dhallType
+                    && typeName haskellType /= outerTypeName
+            , Just haskellType <- List.find predicate haskellTypes -> do
+                let innerName =
+                        Syntax.mkName (Text.unpack (typeName haskellType))
+
+                return (NormalC name [ (bang, ConT innerName) ])
+
         Just (Record kts) -> do
             let process (key, dhallFieldType) = do
                     haskellFieldType <- toNestedHaskellType haskellTypes dhallFieldType
diff --git a/src/Dhall/TypeCheck.hs b/src/Dhall/TypeCheck.hs
--- a/src/Dhall/TypeCheck.hs
+++ b/src/Dhall/TypeCheck.hs
@@ -580,6 +580,16 @@
 
             return VText
 
+        TextReplace ->
+            return
+                (   VHPi "needle" VText  (\_needle ->
+                        VHPi "replacement" VText (\_replacement ->
+                            VHPi "haystack" VText (\_haystack ->
+                                VText
+                            )
+                        )
+                    )
+                )
         TextShow ->
             return (VText ~> VText)
 
@@ -1251,9 +1261,28 @@
 
             return (VConst Type)
 
-        e@With{} ->
-            loop ctx (Syntax.desugarWith e)
+        With e ks v -> do
+            tE' <- loop ctx e
 
+            kTs' <- case tE' of
+                VRecord kTs' -> return kTs'
+                _            -> die (NotWithARecord e (quote names tE'))
+
+            case ks of
+                k :| [] -> do
+                    tV' <- loop ctx v
+
+                    return (VRecord (Dhall.Map.insert k tV' kTs'))
+                k₀ :| k₁ : ks' -> do
+                    let e₁ =
+                            if Dhall.Map.member k₀ kTs'
+                                then Field e (Syntax.makeFieldSelection k₀)
+                                else RecordLit mempty
+
+                    tV' <- loop ctx (With e₁ (k₁ :| ks') v)
+
+                    return (VRecord (Dhall.Map.insert k₀ tV' kTs'))
+
         Note s e ->
             case loop ctx e of
                 Left (TypeError ctx' (Note s' e') m) ->
@@ -1343,6 +1372,7 @@
     | NotAnEquivalence (Expr s a)
     | IncomparableExpression (Expr s a)
     | EquivalenceTypeMismatch (Expr s a) (Expr s a) (Expr s a) (Expr s a)
+    | NotWithARecord (Expr s a) (Expr s a)
     | CantAnd (Expr s a) (Expr s a)
     | CantOr (Expr s a) (Expr s a)
     | CantEQ (Expr s a) (Expr s a)
@@ -4238,6 +4268,45 @@
         \                                                                                \n\
         \" <> insert _R <> "\n"
 
+prettyTypeMessage (NotWithARecord expr0 expr1) = ErrorMessages {..}
+  where
+    short = "❰with❱ only works on records"
+
+    long =
+        "Explanation: You can use ❰with❱ to update a record, like this:                  \n\
+        \                                                                                \n\
+        \                                                                                \n\
+        \    ┌─────────────────────────┐                                                 \n\
+        \    │  { a = 5 } with b = 10  │  This is valid because ❰{ a = 5}❱ is a record   \n\
+        \    └────────────────────────┘                                                  \n\
+        \                                                                                \n\
+        \    ┌──────────────────────────────────────────┐                                \n\
+        \    │  λ(r : { a : Natural }) → r with b = 10  │  This is also valid because    \n\
+        \    └──────────────────────────────────────────┘  ❰r❱ is a record               \n\
+        \                                                                                \n\
+        \                                                                                \n\
+        \... but you cannot use ❰with❱ to update an expression that is not a record.  For\n\
+        \example, the following expression is " <> _NOT <> " valid:                      \n\
+        \                                                                                \n\
+        \                                                                                \n\
+        \    ┌───────────────┐                                                           \n\
+        \    │ 1 with b = 10 │  Invalid: ❰1❱ is not a record                             \n\
+        \    └───────────────┘                                                           \n\
+        \                                                                                \n\
+        \                                                                                \n\
+        \You tried to update the following expressions:                                  \n\
+        \                                                                                \n\
+        \" <> txt0 <> "\n\
+        \                                                                                \n\
+        \... which has type\n\
+        \                                                                                \n\
+        \" <> txt1 <> "\n\
+        \                                                                                \n\
+        \... which is not a record type\n"
+      where
+        txt0 = insert expr0
+        txt1 = insert expr1
+
 prettyTypeMessage (CantAnd expr0 expr1) =
         buildBooleanOperator "&&" expr0 expr1
 
@@ -4649,6 +4718,8 @@
         IncomparableExpression <$> f a
     EquivalenceTypeMismatch a b c d ->
         EquivalenceTypeMismatch <$> f a <*> f b <*> f c <*> f d
+    NotWithARecord a b ->
+        NotWithARecord <$> f a <*> f b
     CantAnd a b ->
         CantAnd <$> f a <*> f b
     CantOr a b ->
diff --git a/tests/Dhall/Test/Import.hs b/tests/Dhall/Test/Import.hs
--- a/tests/Dhall/Test/Import.hs
+++ b/tests/Dhall/Test/Import.hs
@@ -19,6 +19,8 @@
 import qualified Dhall.Import                     as Import
 import qualified Dhall.Parser                     as Parser
 import qualified Dhall.Test.Util                  as Test.Util
+import qualified Network.HTTP.Client              as HTTP
+import qualified Network.HTTP.Client.TLS          as HTTP
 import qualified System.FilePath                  as FilePath
 import qualified Test.Tasty                       as Tasty
 import qualified Test.Tasty.HUnit                 as Tasty.HUnit
@@ -81,8 +83,14 @@
 
         let unsetCache = Turtle.unset "XDG_CACHE_HOME"
 
+        let httpManager =
+                HTTP.newManager
+                    HTTP.tlsManagerSettings
+                        { HTTP.managerResponseTimeout = HTTP.responseTimeoutMicro (120 * 1000 * 1000) }
         let load =
-                State.evalStateT (Test.Util.loadWith actualExpr) (Import.emptyStatus directoryString)
+                State.evalStateT
+                    (Test.Util.loadWith actualExpr)
+                    (Import.emptyStatusWithManager httpManager directoryString)
 
         let usesCache = [ "hashFromCacheA.dhall"
                         , "unit/asLocation/HashA.dhall"
diff --git a/tests/Dhall/Test/QuickCheck.hs b/tests/Dhall/Test/QuickCheck.hs
--- a/tests/Dhall/Test/QuickCheck.hs
+++ b/tests/Dhall/Test/QuickCheck.hs
@@ -374,6 +374,7 @@
             % (1 :: W "Text")
             % (1 :: W "TextLit")
             % (1 :: W "TextAppend")
+            % (1 :: W "TextReplace")
             % (1 :: W "TextShow")
             % (1 :: W "List")
             % (1 :: W "ListLit")
diff --git a/tests/Dhall/Test/TH.hs b/tests/Dhall/Test/TH.hs
--- a/tests/Dhall/Test/TH.hs
+++ b/tests/Dhall/Test/TH.hs
@@ -31,6 +31,21 @@
 deriving instance Eq   Employee
 deriving instance Show Employee
 
+Dhall.TH.makeHaskellTypes
+  [ SingleConstructor "Bar" "MakeBar" "(./tests/th/issue2066.dhall).Bar"
+  , SingleConstructor "Foo" "MakeFoo" "(./tests/th/issue2066.dhall).Foo"
+  , MultipleConstructors "Qux" "(./tests/th/issue2066.dhall).Qux"
+  ]
+
+deriving instance Eq   Bar
+deriving instance Show Bar
+
+deriving instance Eq   Foo
+deriving instance Show Foo
+
+deriving instance Eq   Qux
+deriving instance Show Qux
+
 tests :: TestTree
 tests = Tasty.testGroup "Template Haskell" [ makeHaskellTypeFromUnion ]
 
@@ -51,3 +66,7 @@
     employee <- Dhall.input Dhall.auto "let Department = ./tests/th/Department.dhall in { name = \"John\", department = Department.Marketing }"
 
     Tasty.HUnit.assertEqual "" employee MakeEmployee{ name = "John", department = Marketing }
+
+    qux <- Dhall.input Dhall.auto "let T = ./tests/th/issue2066.dhall in T.Qux.Foo { foo = +2, bar = { baz = +3 } }"
+
+    Tasty.HUnit.assertEqual "" qux (Foo MakeFoo{ foo = 2, bar = MakeBar{ baz = 3 } })
diff --git a/tests/diff/with.txt b/tests/diff/with.txt
new file mode 100644
--- /dev/null
+++ b/tests/diff/with.txt
@@ -0,0 +1,5 @@
+  λ(… : { …
+        })
+→ … with …+ .c.d
+         = - 2
+           + 3
diff --git a/tests/diff/withA.dhall b/tests/diff/withA.dhall
new file mode 100644
--- /dev/null
+++ b/tests/diff/withA.dhall
@@ -0,0 +1,1 @@
+λ(r : { a : Natural }) → r with b = 2
diff --git a/tests/diff/withB.dhall b/tests/diff/withB.dhall
new file mode 100644
--- /dev/null
+++ b/tests/diff/withB.dhall
@@ -0,0 +1,1 @@
+λ(r : { a : Natural }) → r with b.c.d = 3
diff --git a/tests/format/duplicatesA.dhall b/tests/format/duplicatesA.dhall
new file mode 100644
--- /dev/null
+++ b/tests/format/duplicatesA.dhall
@@ -0,0 +1,4 @@
+{ {- Comments around duplicate fields are not preserved -} foo.bar = 1
+, foo = { baz = {- Comments within values are still preserved-} 2 }
+, foo = qux
+}
diff --git a/tests/format/duplicatesB.dhall b/tests/format/duplicatesB.dhall
new file mode 100644
--- /dev/null
+++ b/tests/format/duplicatesB.dhall
@@ -0,0 +1,6 @@
+{ foo.bar = 1
+, foo.baz
+  = {- Comments within values are still preserved-}
+    2
+, foo = qux
+}
diff --git a/tests/format/headerA.dhall b/tests/format/headerA.dhall
--- a/tests/format/headerA.dhall
+++ b/tests/format/headerA.dhall
@@ -1,4 +1,4 @@
    
-{- bla -}
+{- bla -} 
   
 True
diff --git a/tests/format/headerB.dhall b/tests/format/headerB.dhall
--- a/tests/format/headerB.dhall
+++ b/tests/format/headerB.dhall
@@ -1,3 +1,2 @@
 {- bla -}
-
 True
diff --git a/tests/format/headerNoNewlineA.dhall b/tests/format/headerNoNewlineA.dhall
new file mode 100644
--- /dev/null
+++ b/tests/format/headerNoNewlineA.dhall
@@ -0,0 +1,1 @@
+{- -}0
diff --git a/tests/format/headerNoNewlineB.dhall b/tests/format/headerNoNewlineB.dhall
new file mode 100644
--- /dev/null
+++ b/tests/format/headerNoNewlineB.dhall
@@ -0,0 +1,2 @@
+{- -}
+0
diff --git a/tests/format/issue2047A.dhall b/tests/format/issue2047A.dhall
new file mode 100644
--- /dev/null
+++ b/tests/format/issue2047A.dhall
@@ -0,0 +1,4 @@
+let x = ({ foo = 1 } ∧ { bar = 2 })
+  with bar = 3 
+  with foo = 4 
+in x
diff --git a/tests/format/issue2047B.dhall b/tests/format/issue2047B.dhall
new file mode 100644
--- /dev/null
+++ b/tests/format/issue2047B.dhall
@@ -0,0 +1,1 @@
+let x = ({ foo = 1 } ∧ { bar = 2 }) with bar = 3 with foo = 4 in x
diff --git a/tests/format/largeRecordA.dhall b/tests/format/largeRecordA.dhall
--- a/tests/format/largeRecordA.dhall
+++ b/tests/format/largeRecordA.dhall
@@ -2,7 +2,6 @@
 --
 -- To exercise all options documented in https://nethackwiki.com/wiki/Options
 -- see `./unvalidated.dhall`
-
 let types = ./../types.dhall
 
 let defaults = ./../defaults.dhall
diff --git a/tests/format/largeRecordB.dhall b/tests/format/largeRecordB.dhall
--- a/tests/format/largeRecordB.dhall
+++ b/tests/format/largeRecordB.dhall
@@ -2,7 +2,6 @@
 --
 -- To exercise all options documented in https://nethackwiki.com/wiki/Options
 -- see `./unvalidated.dhall`
-
 let types = ./../types.dhall
 
 let defaults = ./../defaults.dhall
diff --git a/tests/lint/success/PreludeExtensionA.dhall b/tests/lint/success/PreludeExtensionA.dhall
new file mode 100644
--- /dev/null
+++ b/tests/lint/success/PreludeExtensionA.dhall
@@ -0,0 +1,1 @@
+https://prelude.dhall-lang.org/List/map
diff --git a/tests/lint/success/PreludeExtensionB.dhall b/tests/lint/success/PreludeExtensionB.dhall
new file mode 100644
--- /dev/null
+++ b/tests/lint/success/PreludeExtensionB.dhall
@@ -0,0 +1,1 @@
+https://prelude.dhall-lang.org/List/map.dhall
diff --git a/tests/lint/success/multiletA.dhall b/tests/lint/success/multiletA.dhall
--- a/tests/lint/success/multiletA.dhall
+++ b/tests/lint/success/multiletA.dhall
@@ -1,5 +1,4 @@
 -- example0.dhall
-
 let Person
     : Type
     =   ∀(Person : Type)
@@ -21,7 +20,7 @@
 
 let everybody
     : Person → List Text
-    = let concat = http://prelude.dhall-lang.org/List/concat
+    = let concat = http://prelude.dhall-lang.org/List/concat.dhall
       
       in    λ(x : Person)
           → x
diff --git a/tests/lint/success/multiletB.dhall b/tests/lint/success/multiletB.dhall
--- a/tests/lint/success/multiletB.dhall
+++ b/tests/lint/success/multiletB.dhall
@@ -1,5 +1,4 @@
 -- example0.dhall
-
 let Person
     : Type
     = ∀(Person : Type) →
@@ -20,7 +19,7 @@
 
 let everybody
     : Person → List Text
-    = let concat = http://prelude.dhall-lang.org/List/concat
+    = let concat = http://prelude.dhall-lang.org/List/concat.dhall
 
       in  λ(x : Person) →
             x
diff --git a/tests/lint/success/regression0A.dhall b/tests/lint/success/regression0A.dhall
--- a/tests/lint/success/regression0A.dhall
+++ b/tests/lint/success/regression0A.dhall
@@ -1,4 +1,4 @@
-    let replicate = https://prelude.dhall-lang.org/List/replicate
+    let replicate = https://prelude.dhall-lang.org/List/replicate.dhall
 
 in  let Config = { name : Text, age : Natural }
 
diff --git a/tests/lint/success/regression0B.dhall b/tests/lint/success/regression0B.dhall
--- a/tests/lint/success/regression0B.dhall
+++ b/tests/lint/success/regression0B.dhall
@@ -1,3 +1,3 @@
-let replicate = https://prelude.dhall-lang.org/List/replicate
+let replicate = https://prelude.dhall-lang.org/List/replicate.dhall
 
 in  replicate 10 Text "!"
diff --git a/tests/th/issue2066.dhall b/tests/th/issue2066.dhall
new file mode 100644
--- /dev/null
+++ b/tests/th/issue2066.dhall
@@ -0,0 +1,7 @@
+let Bar = { baz : Integer }
+
+let Foo = { foo : Integer, bar : Bar }
+
+let Qux = < Foo : Foo | Bar : Bar >
+
+in  { Foo, Bar, Qux }
