diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,131 @@
 
 ---
 
+## [0.17.5] - 2026-08-19
+
+Point release on the 0.17.x line. Two language-surface changes lead: sum-type eliminators unify on
+`match` (scrutinee-first), and the primitive set is tentatively finalized — `strings.lines`/`unlines`
+are removed in favour of `hydra.formatting` term helpers. A symlink-aware filesystem family lands
+across all ten hosts, and Hydra's own build system continues its migration into Hydra.
+
+**Backward-incompatible.** The `cases` -> `match` rename and the `strings.lines`/`unlines` removal
+both change the published kernel surface. Code written against 0.17.4 that uses `Optionals.cases`
+or `strings.lines`/`strings.unlines` must be updated.
+
+### Highlights
+
+- **Sum-type eliminators unify on `match`** ([#615](https://github.com/CategoricalData/hydra/issues/615)):
+  the `cases`/`match` helper pair is flipped to a single scrutinee-first `match` convention across the
+  Haskell, Java, Python, and Scala DSLs, the `optionals.cases` -> `optionals.match` kernel primitive,
+  and the corresponding implementations in TypeScript and all four Lisp dialects.
+- **Primitive set tentatively finalized** ([#417](https://github.com/CategoricalData/hydra/issues/417)):
+  `strings.lines` and `strings.unlines` are removed as primitives; their semantics are preserved as
+  `hydra.formatting.lines`/`unlines` term helpers, with overlay implementations dropped across all ten
+  hosts and callers repointed.
+- **Symlink-aware filesystem primitives** ([#666](https://github.com/CategoricalData/hydra/issues/666)):
+  `status(followLinks)`, `createSymlink`, and `readSymlink` land with native implementations for every
+  host — Haskell, Java, Python, Scala, TypeScript, Clojure, Common Lisp, Scheme, and Emacs Lisp.
+- **Build system promotion continues** ([#416](https://github.com/CategoricalData/hydra/issues/416)):
+  adds `hydra.build.walk` extension-glob helpers (`extensionOf`/`filterByExtension`/`matchesExtension`)
+  and `hydra.build.comparereportlogic`, a set of pure snapshot-compare decision helpers.
+
+### Bug fixes
+
+- **`math.range` was inclusive of both bounds** ([#647](https://github.com/CategoricalData/hydra/issues/647)),
+  silently fabricating an extra element in index arithmetic.
+- **Java coder TCO-`cases` codegen** dropped enclosing-method type parameters from union-variant casts
+  (found via [#666](https://github.com/CategoricalData/hydra/issues/666)).
+- **`ShaclRdf` promoted to a DSL module** ([#652](https://github.com/CategoricalData/hydra/issues/652))
+  so the SHACL pipeline works outside Haskell.
+- **Cold-seed shim portability**: the R22 bootstrap shim used GNU-only `\+` and `\b`, which fail under
+  BSD `sed` on macOS ([#417](https://github.com/CategoricalData/hydra/issues/417)).
+- **Bootstrap Haskell target missing `unix`**: the demo's static `package.yaml` was not updated when
+  `System.Posix.Files` entered the kernel overlay, breaking every `*-to-haskell` bootstrap cell
+  ([#670](https://github.com/CategoricalData/hydra/issues/670)).
+- **Bootstrap comparison scored Scala and TypeScript cells as passing without comparing anything**:
+  `compare_output`'s target switch was missing both languages, so the baseline path was malformed,
+  every file counted as "no baseline found", and a zero-file comparison reported `pass`. A Scala or
+  TypeScript *target* cell could never fail ([#671](https://github.com/CategoricalData/hydra/issues/671)).
+
+### Known issues
+
+- A pre-#630 post-generation text pass rewrites `hydra.lib.<sub>` -> `hydra.overlay.<lang>.lib.<sub>`
+  in generated **doc comments** as well as code, because its quote-prefix guard does not recognize
+  mid-sentence prose references. Affects two kernel doc strings in `src/main`
+  (`hydra.error.system`, `hydra.error.packaging`) plus ~20 generated docstrings in the test tree;
+  cosmetic only, no behavioral impact. Tracked as part of
+  [#633](https://github.com/CategoricalData/hydra/issues/633).
+- Bootstrap comparison diff detail is not persisted to the run directory
+  ([#671](https://github.com/CategoricalData/hydra/issues/671)).
+
+---
+
+## [0.17.4] - 2026-08-09
+
+Point release on the 0.17.x line. Fixes an inference bug that mis-typed generated Java and Python for
+`readFile`, adds the `divide` primitive, and restores `hydra-ext` to the published package set. Release
+validation also surfaced a family of pre-existing cross-host code-generation defects — none of which the
+per-host CI jobs can catch, because only the bootstrap exercises one host generating *another*.
+
+### Highlights
+
+- **Output-only nominal generalization fixed** ([#637](https://github.com/CategoricalData/hydra/issues/637),
+  with [#638](https://github.com/CategoricalData/hydra/issues/638) /
+  [#639](https://github.com/CategoricalData/hydra/issues/639) /
+  [#640](https://github.com/CategoricalData/hydra/issues/640)): a nominal type appearing only in the
+  *output* position of a primitive's signature was generalized to a free type variable instead of resolving
+  as nominal, mis-typing the generated Java and Python for `readFile`. Also widens universe closure and adds
+  a `kernelTypeUniverse` helper, an effect DSL builder, and `effects`/`files`/`text`/`system` lib wrappers.
+- **`divide` primitive** ([#317](https://github.com/CategoricalData/hydra/issues/317)): now present in the
+  published kernel. This also clears the cold-clone dangle, since a cold seed against published 0.17.4
+  resolves `DefMath.divide`.
+- **`hydra-ext` republished** ([#636](https://github.com/CategoricalData/hydra/issues/636)): back in the
+  published set after its absence from 0.17.1–0.17.3, shipping to Hackage and PyPI.
+
+### Bug fixes
+
+- **Overlay-lib redirection skipped for the Haskell target**
+  ([#630](https://github.com/CategoricalData/hydra/issues/630)):
+  the Java, Python, Scheme, Clojure and Common Lisp heads resolved the overlay lib directory using an
+  all-lowercase path and did not lower-case the names they scanned. Haskell's overlay tree is capitalized
+  (`Hydra/Overlay/Haskell/Lib/`), so every `hydra.lib.*` redirect silently failed and the generated Haskell
+  imported `Hydra.Lib.*` instead of `Hydra.Overlay.Haskell.Lib.*`, producing hundreds of type errors. The
+  defect was invisible on case-sensitive filesystems, where the failed directory check falls back to a
+  hard-coded list that happens to be correct. The Python head carried *two* independent copies of this scan;
+  only the one in `generation.py` feeds the Haskell coder.
+- **Lisp-as-host bootstrap** ([#520](https://github.com/CategoricalData/hydra/issues/520),
+  [#630](https://github.com/CategoricalData/hydra/issues/630)): the four Lisp head decode drivers called
+  `from_json` with a stale 4-argument signature, and the Lisp bootstrap-driver coders were not pre-bound with
+  `overlaySubs`.
+- **Python-as-host dropped the `Graph` argument** ([#630](https://github.com/CategoricalData/hydra/issues/630)):
+  `overlaySubs` was not threaded into the Python head's `write_*` wrappers.
+- **Clojure `resolve-coder` and `decimal-to-float32`**
+  ([#630](https://github.com/CategoricalData/hydra/issues/630)): a stray parenthesis closed a `case` early,
+  making an unsupported-default block run unconditionally; and `(float (.doubleValue ...))` threw on
+  `Float.MAX_VALUE`, now saturating via `(.floatValue (bigdec x))`.
+- **Cold-seeder failed on macOS** ([#630](https://github.com/CategoricalData/hydra/issues/630)): the #376
+  cold seeder used a bare `sed -i -e`, which is GNU-only and aborts immediately under BSD `sed`.
+
+### Release engineering
+
+- **Review checkpoint before Maven Central publishes**
+  ([#591](https://github.com/CategoricalData/hydra/issues/591)): `HYDRA_JAVA_PUBLISH_HOLD=1` uploads the
+  aggregated Java deployment as `USER_MANAGED`, so it validates and then holds for review instead of
+  publishing automatically. This mirrors `HYDRA_SCALA_PUBLISH_HOLD` and makes an upload reversible — a held
+  deployment can be dropped, whereas an automatic one cannot be undone.
+
+### Known issues
+
+- **`hydra-ext` is not published to Maven Central**
+  ([#643](https://github.com/CategoricalData/hydra/issues/643)): it does not compile for the Java target,
+  because the visitor-pattern inner interface the Java coder emits collides with the enclosing `Visitor`
+  type in `hydra.cpp.syntax`. Only Java is affected; the Python coder emits sibling classes rather than
+  nested ones. ext ships to Hackage and PyPI at 0.17.4 and is expected to rejoin the Java set once fixed.
+- **TypeScript no longer self-hosts**
+  ([#642](https://github.com/CategoricalData/hydra/issues/642)): the TypeScript host's JSON decoder fails to
+  decode most of the kernel, so `typescript-as-host` code generation is broken. No published artifact is
+  affected — `dist/typescript` is generated by the Haskell host and passes its test suite.
+
 ## [0.17.3] - 2026-08-01
 
 Point release on the 0.17.x line, focused on **release-artifact integrity**. The 0.17.2 release shipped
diff --git a/hydra-haskell.cabal b/hydra-haskell.cabal
--- a/hydra-haskell.cabal
+++ b/hydra-haskell.cabal
@@ -1,11 +1,11 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.39.1.
+-- This file has been generated from package.yaml by hpack version 0.38.1.
 --
 -- see: https://github.com/sol/hpack
 
 name:           hydra-haskell
-version:        0.17.4
+version:        0.17.5
 synopsis:       Hydra's Haskell coder: emit Haskell source from Hydra modules
 description:    Hydra is an implementation of the LambdaGraph data model, which takes advantage of an isomorphism between labeled hypergraphs and typed lambda calculus: in Hydra, "graphs are programs, and programs are graphs". This package is Hydra's Haskell coder: it translates Hydra modules into Haskell source. The top-level entry point is moduleToHaskell (and moduleToHaskellModule for the structured AST). It builds on hydra-kernel.
 category:       Data
@@ -44,6 +44,6 @@
   build-depends:
       base >=4.19.0 && <4.22
     , containers >=0.6.7 && <0.8
-    , hydra-kernel ==0.17.4
+    , hydra-kernel ==0.17.5
     , scientific >=0.3.7 && <0.4
   default-language: Haskell2010
diff --git a/src/main/haskell/Hydra/Dsl/Haskell/Environment.hs b/src/main/haskell/Hydra/Dsl/Haskell/Environment.hs
--- a/src/main/haskell/Hydra/Dsl/Haskell/Environment.hs
+++ b/src/main/haskell/Hydra/Dsl/Haskell/Environment.hs
@@ -7,7 +7,7 @@
 import qualified Hydra.Core as Core
 import qualified Hydra.Haskell.Environment as Environment
 import qualified Hydra.Typed as Typed
-import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines)
 import qualified Data.Scientific as Sci
 
 -- | DSL constructor for hydra.haskell.environment.HaskellModuleMetadata
diff --git a/src/main/haskell/Hydra/Dsl/Haskell/Syntax.hs b/src/main/haskell/Hydra/Dsl/Haskell/Syntax.hs
--- a/src/main/haskell/Hydra/Dsl/Haskell/Syntax.hs
+++ b/src/main/haskell/Hydra/Dsl/Haskell/Syntax.hs
@@ -8,7 +8,7 @@
 import qualified Hydra.Dsl.Core as DslCore
 import qualified Hydra.Haskell.Syntax as Syntax
 import qualified Hydra.Typed as Typed
-import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines)
 import qualified Data.Scientific as Sci
 
 -- | DSL constructor for hydra.haskell.syntax.Alternative
diff --git a/src/main/haskell/Hydra/Haskell/Coder.hs b/src/main/haskell/Hydra/Haskell/Coder.hs
--- a/src/main/haskell/Hydra/Haskell/Coder.hs
+++ b/src/main/haskell/Hydra/Haskell/Coder.hs
@@ -67,7 +67,7 @@
 import qualified Hydra.Validation as Validation
 import qualified Hydra.Variables as Variables
 import qualified Hydra.Variants as Variants
-import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines)
 import qualified Data.Scientific as Sci
 import qualified Data.Map as M
 import qualified Data.Set as S
@@ -160,9 +160,11 @@
                             "decodeFloat",
                             "encodeFloat",
                             "fail",
+                            "lines",
                             "map",
                             "pure",
-                            "sum"])],
+                            "sum",
+                            "unlines"])],
                       [
                         (("Data.Scientific", (Just "Sci")), [])],
                       (condImport (Environment.haskellModuleMetadataUsesByteString meta) (("Data.ByteString", (Just "B")), [])),
@@ -211,7 +213,7 @@
                         v1 = Logic.ifElse (Variables.isFreeVariableInTerm (Core.Name v0) rhsTerm) Constants.ignoredVariable v0
                         hname =
                                 Utils.unionFieldReference (Sets.union (Sets.fromList (Maps.keys (Graph.graphBoundTerms g))) (Sets.fromList (Maps.keys (Graph.graphSchemaTypes g)))) namespaces dn fn
-                    in (Eithers.bind (Optionals.cases (Maps.lookup fn fieldMap) (Left (Errors.ErrorResolution (Errors.ResolutionErrorNoMatchingField (Errors.NoMatchingFieldError {
+                    in (Eithers.bind (Optionals.match (Maps.lookup fn fieldMap) (Left (Errors.ErrorResolution (Errors.ResolutionErrorNoMatchingField (Errors.NoMatchingFieldError {
                       Errors.noMatchingFieldErrorFieldName = fn})))) (\fieldType ->
                       let ft = Core.fieldTypeType fieldType
                           noArgs = []
@@ -228,7 +230,7 @@
       in (Eithers.bind (Resolution.requireUnionType cx g dn) (\rt ->
         let toFieldMapEntry = \f -> (Core.fieldTypeName f, f)
             fieldMap = Maps.fromList (Lists.map toFieldMapEntry rt)
-        in (Eithers.bind (Eithers.mapList (toAlt fieldMap) fields) (\ecases -> Eithers.bind (Optionals.cases def (Right []) (\d -> Eithers.bind (Eithers.map (\x -> Syntax.CaseRhs x) (encodeTerm depth namespaces d cx g)) (\cs ->
+        in (Eithers.bind (Eithers.mapList (toAlt fieldMap) fields) (\ecases -> Eithers.bind (Optionals.match def (Right []) (\d -> Eithers.bind (Eithers.map (\x -> Syntax.CaseRhs x) (encodeTerm depth namespaces d cx g)) (\cs ->
           let lhs = Syntax.PatternName (Utils.rawName Constants.ignoredVariable)
               alt =
                       Syntax.Alternative {
@@ -344,7 +346,7 @@
         Core.TermList v0 -> Eithers.bind (Eithers.mapList encode v0) (\helems -> Right (Syntax.ExpressionList helems))
         Core.TermLiteral v0 -> encodeLiteral v0 cx
         Core.TermMap v0 -> Logic.ifElse (Maps.null v0) (Right (Utils.hsvar "M.empty")) (nonemptyMap v0)
-        Core.TermOptional v0 -> Optionals.cases v0 (Right (Utils.hsvar "Nothing")) (\t -> Eithers.bind (encode t) (\ht -> Right (Utils.hsapp (Utils.hsvar "Just") ht)))
+        Core.TermOptional v0 -> Optionals.match v0 (Right (Utils.hsvar "Nothing")) (\t -> Eithers.bind (encode t) (\ht -> Right (Utils.hsapp (Utils.hsvar "Just") ht)))
         Core.TermPair v0 -> Eithers.bind (encode (Pairs.first v0)) (\f -> Eithers.bind (encode (Pairs.second v0)) (\s -> Right (Syntax.ExpressionTuple [
           f,
           s])))
@@ -562,7 +564,7 @@
                 Packaging.DefinitionTerm v0 ->
                   let term = Packaging.termDefinitionBody v0
                       metaWithTerm = Rewriting.foldOverTerm Coders.TraversalOrderPre (\m -> \t -> extendMetaForTerm m t) meta term
-                  in (Optionals.cases (Optionals.map Scoping.termSignatureToTypeScheme (Packaging.termDefinitionSignature v0)) metaWithTerm (\ts -> Rewriting.foldOverType Coders.TraversalOrderPre (\m -> \t -> extendMetaForType m t) metaWithTerm (Core.typeSchemeBody ts)))
+                  in (Optionals.match (Optionals.map Scoping.termSignatureToTypeScheme (Packaging.termDefinitionSignature v0)) metaWithTerm (\ts -> Rewriting.foldOverType Coders.TraversalOrderPre (\m -> \t -> extendMetaForType m t) metaWithTerm (Core.typeSchemeBody ts)))
                 Packaging.DefinitionType v0 ->
                   let typ = Core.typeSchemeBody (Packaging.typeDefinitionBody v0)
                   in (Rewriting.foldOverType Coders.TraversalOrderPre (\m -> \t -> extendMetaForType m t) meta typ)
@@ -699,16 +701,16 @@
                           terms = Lists.map Core.bindingTerm lbindings
                       in (Eithers.bind (Eithers.mapList (\t -> encodeTerm 0 namespaces t cx g) terms) (\hterms ->
                         let hbindings = Lists.zipWith toTermDefinition hnames hterms
-                            prevBindings = Optionals.cases bindings [] (\lb -> Syntax.unLocalBindings lb)
+                            prevBindings = Optionals.match bindings [] (\lb -> Syntax.unLocalBindings lb)
                             allBindings = Lists.concat2 prevBindings hbindings
                         in (toDecl comments hname_ env (Just (Syntax.LocalBindings allBindings)))))
                     _ -> Eithers.bind (encodeTerm 0 namespaces term_ cx g) (\hterm ->
                       let vb = Utils.simpleValueBinding hname_ hterm bindings
-                          schemeConstraints = Optionals.cases typ Nothing (\ts -> Core.typeSchemeConstraints ts)
+                          schemeConstraints = Optionals.match typ Nothing (\ts -> Core.typeSchemeConstraints ts)
                           schemeClasses = typeSchemeConstraintsToClassMap schemeConstraints
                       in (Eithers.bind (Annotations.getTypeClasses cx g (Strip.removeTypesFromTerm term)) (\explicitClasses ->
                         let combinedClasses = Maps.union schemeClasses explicitClasses
-                            schemeType = Optionals.cases typ Core.TypeUnit (\ts -> Core.typeSchemeBody ts)
+                            schemeType = Optionals.match typ Core.TypeUnit (\ts -> Core.typeSchemeBody ts)
                         in (Eithers.bind (encodeTypeWithClassAssertions namespaces combinedClasses schemeType cx g) (\htype ->
                           let decl =
                                   Syntax.DeclarationTypedBinding (Syntax.TypedBinding {
@@ -894,7 +896,7 @@
       let constraintToName =
               \tcc -> case tcc of
                 Core.TypeClassConstraintSimple v0 -> Just v0
-      in (Optionals.cases maybeConstraints Maps.empty (\constraints -> Maps.map (\meta -> Sets.fromList (Optionals.givens (Lists.map constraintToName (Core.typeVariableConstraintsClasses meta)))) constraints))
+      in (Optionals.match maybeConstraints Maps.empty (\constraints -> Maps.map (\meta -> Sets.fromList (Optionals.givens (Lists.map constraintToName (Core.typeVariableConstraintsClasses meta)))) constraints))
 
 -- | Whether to use the Hydra core import in generated modules
 useCoreImport :: Bool
diff --git a/src/main/haskell/Hydra/Haskell/Environment.hs b/src/main/haskell/Hydra/Haskell/Environment.hs
--- a/src/main/haskell/Hydra/Haskell/Environment.hs
+++ b/src/main/haskell/Hydra/Haskell/Environment.hs
@@ -5,7 +5,7 @@
 module Hydra.Haskell.Environment where
 
 import qualified Hydra.Core as Core
-import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines)
 import qualified Data.Scientific as Sci
 
 -- | Metadata used to determine which standard imports are needed in a generated Haskell module
diff --git a/src/main/haskell/Hydra/Haskell/Language.hs b/src/main/haskell/Hydra/Haskell/Language.hs
--- a/src/main/haskell/Hydra/Haskell/Language.hs
+++ b/src/main/haskell/Hydra/Haskell/Language.hs
@@ -35,7 +35,7 @@
 import qualified Hydra.Util as Util
 import qualified Hydra.Validation as Validation
 import qualified Hydra.Variants as Variants
-import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines)
 import qualified Data.Scientific as Sci
 import qualified Data.Set as S
 
diff --git a/src/main/haskell/Hydra/Haskell/Operators.hs b/src/main/haskell/Hydra/Haskell/Operators.hs
--- a/src/main/haskell/Hydra/Haskell/Operators.hs
+++ b/src/main/haskell/Hydra/Haskell/Operators.hs
@@ -35,7 +35,7 @@
 import qualified Hydra.Util as Util
 import qualified Hydra.Validation as Validation
 import qualified Hydra.Variants as Variants
-import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines)
 import qualified Data.Scientific as Sci
 
 -- | Logical AND operator (&&)
diff --git a/src/main/haskell/Hydra/Haskell/Serde.hs b/src/main/haskell/Hydra/Haskell/Serde.hs
--- a/src/main/haskell/Hydra/Haskell/Serde.hs
+++ b/src/main/haskell/Hydra/Haskell/Serde.hs
@@ -20,6 +20,7 @@
 import qualified Hydra.Error.System as ErrorSystem
 import qualified Hydra.Errors as Errors
 import qualified Hydra.File as File
+import qualified Hydra.Formatting as Formatting
 import qualified Hydra.Graph as Graph
 import qualified Hydra.Haskell.Operators as Operators
 import qualified Hydra.Haskell.Syntax as Syntax
@@ -50,7 +51,7 @@
 import qualified Hydra.Util as Util
 import qualified Hydra.Validation as Validation
 import qualified Hydra.Variants as Variants
-import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines)
 import qualified Data.Scientific as Sci
 
 -- | Convert a pattern-matching alternative to an AST expression
@@ -135,7 +136,7 @@
                           fields = Syntax.recordConstructorFields v0
                       in (Serialization.spaceSep (Lists.cons (nameToExpr name) [
                         Serialization.curlyBracesList Nothing Serialization.halfBlockStyle (Lists.map fieldToExpr fields)]))
-      in (Optionals.cases mc body (\c -> Serialization.newlineSep (Lists.cons (Serialization.cst (toHaskellComments c)) [
+      in (Optionals.match mc body (\c -> Serialization.newlineSep (Lists.cons (Serialization.cst (toHaskellComments c)) [
         body])))
 
 -- | Convert a data/newtype keyword to an AST expression
@@ -202,7 +203,7 @@
                         (Serialization.cst "::"),
                         (typeToExpr htype)]) [
                         valueBindingToExpr vb]))
-      in (Optionals.cases mc body (\c -> Serialization.newlineSep (Lists.cons (Serialization.cst (toHaskellComments c)) [
+      in (Optionals.match mc body (\c -> Serialization.newlineSep (Lists.cons (Serialization.cst (toHaskellComments c)) [
         body])))
 
 -- | Convert a Haskell expression to an AST expression
@@ -237,7 +238,7 @@
           mc = Syntax.fieldComments field
           body = Serialization.spaceSep (Lists.cons (nameToExpr name) (Lists.cons (Serialization.cst "::") [
                 typeToExpr typ]))
-      in (Optionals.cases mc body (\c -> Serialization.newlineSep (Lists.cons (Serialization.cst (toHaskellComments c)) [
+      in (Optionals.match mc body (\c -> Serialization.newlineSep (Lists.cons (Serialization.cst (toHaskellComments c)) [
         body])))
 
 -- | Render a 'EntityReference' as Haddock link syntax
@@ -346,7 +347,7 @@
           head =
                   Serialization.spaceSep (Lists.cons (Serialization.cst "module") (Lists.cons (Serialization.cst mname) [
                     Serialization.cst "where"]))
-      in (Optionals.cases mc head (\c -> Serialization.newlineSep (Lists.cons (Serialization.cst (toHaskellComments c)) (Lists.cons (Serialization.cst "") [
+      in (Optionals.match mc head (\c -> Serialization.newlineSep (Lists.cons (Serialization.cst (toHaskellComments c)) (Lists.cons (Serialization.cst "") [
         head]))))
 
 -- | Convert a Haskell module to an AST expression
@@ -358,7 +359,7 @@
           decls = Syntax.moduleDeclarations module_
           warning = [
                 Serialization.cst (toSimpleComments Constants.warningAutoGeneratedFile)]
-          headerLine = Optionals.cases mh [] (\h -> [
+          headerLine = Optionals.match mh [] (\h -> [
                 moduleHeadToExpr h])
           declLines = Lists.map declarationToExpr decls
           importLines = Logic.ifElse (Lists.null imports) [] [
@@ -417,12 +418,12 @@
 -- | Convert a string to Haddock documentation comments. Empty source lines emit `-- |` (no trailing space) so blank doc lines don't carry trailing whitespace into the generated file. Doc-escape tags are rendered as Haddock links via haddockEntityRef.
 toHaskellComments :: String -> String
 toHaskellComments c =
-    Strings.join "\n" (Lists.map (\s -> Logic.ifElse (Equality.equal s "") "-- |" (Strings.concat2 "-- | " s)) (Strings.lines (PrintDocs.renderDocStringWith haddockEntityRef c)))
+    Strings.join "\n" (Lists.map (\s -> Logic.ifElse (Equality.equal s "") "-- |" (Strings.concat2 "-- | " s)) (Formatting.lines (PrintDocs.renderDocStringWith haddockEntityRef c)))
 
 -- | Convert a string to simple line comments. Empty source lines emit `--` (no trailing space) for the same reason as toHaskellComments.
 toSimpleComments :: String -> String
 toSimpleComments c =
-    Strings.join "\n" (Lists.map (\s -> Logic.ifElse (Equality.equal s "") "--" (Strings.concat2 "-- " s)) (Strings.lines c))
+    Strings.join "\n" (Lists.map (\s -> Logic.ifElse (Equality.equal s "") "--" (Strings.concat2 "-- " s)) (Formatting.lines c))
 
 -- | Convert a type signature to an AST expression
 typeSignatureToExpr :: Syntax.TypeSignature -> Ast.Expr
@@ -485,7 +486,7 @@
                         lhsExpr,
                         (Serialization.cst "=")],
                       (Serialization.tabIndent rhsExpr)])
-        in (Optionals.cases local body (\localBindings ->
+        in (Optionals.match local body (\localBindings ->
           let bindings = Syntax.unLocalBindings localBindings
           in (Serialization.indentBlock (Lists.cons body [
             Serialization.indentBlock (Lists.cons (Serialization.cst "where") (Lists.map localBindingToExpr bindings))]))))
diff --git a/src/main/haskell/Hydra/Haskell/Syntax.hs b/src/main/haskell/Hydra/Haskell/Syntax.hs
--- a/src/main/haskell/Hydra/Haskell/Syntax.hs
+++ b/src/main/haskell/Hydra/Haskell/Syntax.hs
@@ -5,7 +5,7 @@
 module Hydra.Haskell.Syntax where
 
 import qualified Hydra.Core as Core
-import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines)
 import qualified Data.Scientific as Sci
 
 -- | A pattern-matching alternative
diff --git a/src/main/haskell/Hydra/Haskell/Testing.hs b/src/main/haskell/Hydra/Haskell/Testing.hs
--- a/src/main/haskell/Hydra/Haskell/Testing.hs
+++ b/src/main/haskell/Hydra/Haskell/Testing.hs
@@ -57,7 +57,7 @@
 import qualified Hydra.Util as Util
 import qualified Hydra.Validation as Validation
 import qualified Hydra.Variants as Variants
-import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines)
 import qualified Data.Scientific as Sci
 import qualified Data.Set as S
 
diff --git a/src/main/haskell/Hydra/Haskell/Utils.hs b/src/main/haskell/Hydra/Haskell/Utils.hs
--- a/src/main/haskell/Hydra/Haskell/Utils.hs
+++ b/src/main/haskell/Hydra/Haskell/Utils.hs
@@ -50,7 +50,7 @@
 import qualified Hydra.Util as Util
 import qualified Hydra.Validation as Validation
 import qualified Hydra.Variants as Variants
-import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines)
 import qualified Data.Scientific as Sci
 import qualified Data.Set as S
 
@@ -73,7 +73,7 @@
           local = Util.qualifiedNameLocal qname
           escLocal = sanitizeHaskellName local
           mns = Util.qualifiedNameModuleName qname
-      in (Optionals.cases (Util.qualifiedNameModuleName qname) (simpleName local) (\ns -> Optionals.cases (Maps.lookup ns namespacesMap) (simpleName local) (\mn ->
+      in (Optionals.match (Util.qualifiedNameModuleName qname) (simpleName local) (\ns -> Optionals.match (Maps.lookup ns namespacesMap) (simpleName local) (\mn ->
         let aliasStr = Syntax.unModuleName mn
         in (Logic.ifElse (Equality.equal ns gname) (simpleName escLocal) (rawName (Strings.concat [
           aliasStr,
@@ -148,7 +148,7 @@
                                   let segCount = Pairs.first (Pairs.second (Pairs.second e))
                                       k = Pairs.second (Pairs.second (Pairs.second e))
                                       existing = Maps.lookup k m
-                                  in (Maps.insert k (Optionals.cases existing segCount (\prev -> Logic.ifElse (Ordering.lt segCount prev) segCount prev)) m)) Maps.empty aliasEntries
+                                  in (Maps.insert k (Optionals.match existing segCount (\prev -> Logic.ifElse (Ordering.lt segCount prev) segCount prev)) m)) Maps.empty aliasEntries
                         aliasMinSegsCount =
                                 Lists.foldl (\m -> \e ->
                                   let segCount = Pairs.first (Pairs.second (Pairs.second e))
