packages feed

hydra-haskell 0.17.5 → 0.17.6

raw patch · 12 files changed

+302/−31 lines, 12 filesdep ~hydra-kernelPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: hydra-kernel

API changes (from Hackage documentation)

+ Hydra.Dsl.Haskell.Environment: haskellModuleMetadataUsesVoid :: TypedTerm HaskellModuleMetadata -> TypedTerm Bool
+ Hydra.Dsl.Haskell.Environment: haskellModuleMetadataWithUsesVoid :: TypedTerm HaskellModuleMetadata -> TypedTerm Bool -> TypedTerm HaskellModuleMetadata
+ Hydra.Haskell.Coder: setMetaUsesVoid :: Bool -> HaskellModuleMetadata -> HaskellModuleMetadata
+ Hydra.Haskell.Environment: [haskellModuleMetadataUsesVoid] :: HaskellModuleMetadata -> Bool
+ Hydra.Haskell.Environment: _HaskellModuleMetadata_usesVoid :: Name
- Hydra.Dsl.Haskell.Environment: haskellModuleMetadata :: TypedTerm Bool -> TypedTerm Bool -> TypedTerm Bool -> TypedTerm Bool -> TypedTerm HaskellModuleMetadata
+ Hydra.Dsl.Haskell.Environment: haskellModuleMetadata :: TypedTerm Bool -> TypedTerm Bool -> TypedTerm Bool -> TypedTerm Bool -> TypedTerm Bool -> TypedTerm HaskellModuleMetadata
- Hydra.Haskell.Coder: typeSchemeConstraintsToClassMap :: Ord t0 => Maybe (Map t0 TypeVariableConstraints) -> Map t0 (Set Name)
+ Hydra.Haskell.Coder: typeSchemeConstraintsToClassMap :: Ord t0 => Map t0 TypeVariableConstraints -> Map t0 (Set Name)
- Hydra.Haskell.Environment: HaskellModuleMetadata :: Bool -> Bool -> Bool -> Bool -> HaskellModuleMetadata
+ Hydra.Haskell.Environment: HaskellModuleMetadata :: Bool -> Bool -> Bool -> Bool -> Bool -> HaskellModuleMetadata

Files

CHANGELOG.md view
@@ -15,6 +15,168 @@  --- +## [0.17.6] - 2026-08-30++Point release on the 0.17.x line, and the last backward-incompatible batch before the 1.0 surface+freeze. Five kernel-surface changes land together as the "0.17 breaking batch":+`null` becomes `isEmpty`, `read*`/`show*` become `parse*`/`print*`, `TypeScheme.constraints` and+`TypeVariableConstraints.classes` change shape, and the constructor primitives are finalized.+Alongside them, a genuine soundness gap in type inference is fixed — class constraints now propagate+through function-domain positions — and the cold-seed path is rebuilt on the Java host so that+breaking core-type changes are no longer structurally impossible to bootstrap.++**Backward-incompatible.** All five surface changes below alter the published kernel. Code written+against 0.17.5 must be updated:++- **[#682]** `hydra.lib.{lists,sets,maps,strings}.null` -> `.isEmpty`.+- **[#691]** the `read*`/`show*` family -> `parse*`/`print*`.+- **[#683]** `TypeScheme.constraints`: `optional<map>` -> plain `map`.+- **[#685]** `TypeVariableConstraints.classes`: `list` -> `set`.+- **[#687]** constructor primitives finalized: `lists.pure` is removed; `optionals.given`,+  `eithers.left`/`right` and `pairs.pair` are added.++[#682]: https://github.com/CategoricalData/hydra/issues/682+[#683]: https://github.com/CategoricalData/hydra/issues/683+[#685]: https://github.com/CategoricalData/hydra/issues/685+[#687]: https://github.com/CategoricalData/hydra/issues/687+[#691]: https://github.com/CategoricalData/hydra/issues/691++### Highlights++- **Class constraints propagate through contravariant positions**+  ([#702](https://github.com/CategoricalData/hydra/issues/702)): inference silently dropped a class+  constraint when the constrained type variable was bound through the **domain** (input) position of a+  higher-order function argument, while transferring it correctly in output positions — a real soundness+  gap in the type checker. It had been papered over twice by freezing `encodeMap`/`encodeSet` to+  monomorphic `Int`. Both freezes and the [#554](https://github.com/CategoricalData/hydra/issues/554)+  `toPrimitive` stopgap are now removed, the definitions re-polymorphized, and a domain-position+  regression test added. A `sets.filter` overlay lands across Java, Python, Scala, TypeScript and the+  Lisp dialects as its first consumer.+- **Cold-seed rebuilt on the Java host**+  ([#703](https://github.com/CategoricalData/hydra/issues/703)): CI's cold-seed steps compiled HEAD's+  kernel `Types` source against the *published* Hackage `hydra-kernel`, which is sound only for additive+  changes and structurally impossible for any breaking core-type-shape change — the root of a recurring+  red-CI class (#500, #608, #617, #417, #683). The Haskell cold-seeder (`ColdSeedMain`, `typesmods/`,+  Check-2) is deleted and replaced by a data-driven Java-host schema-walking seed+  (`seed-dist-haskell.sh`), which decodes `dist/json` and emits Haskell text without ever linking+  HEAD types against a published kernel.+- **`hydra.paths` completed** ([#716](https://github.com/CategoricalData/hydra/issues/716)):+  the step unions are realigned with the `hydra.core` term and type grammars — missing variants+  added (`annotatedAnnotation`, `eitherLeft`/`eitherRight`, `effect`), undirected steps given a+  direction, and variants named after retired constructors renamed. `hydra.print.paths` is rewritten+  as serialization-only (printers, parsers and a round-trip law), and the graph view moves to a new+  `hydra.shredding` module (`shredGraph`/`shredTerm`/`shredSchema`), which the Graphviz coder now+  consumes.+- **`hydra.lib.ordering` is genuinely structural on every host**+  ([#718](https://github.com/CategoricalData/hydra/issues/718)): the Java, Python and Scala overlay+  implementations fell back to comparing *printed strings* for non-literal and mixed-variant terms,+  contradicting the normative `ordering-and-equality.md` (records field-by-field in declaration+  order, unions by declared-variant order then payload, wrappers by wrapped value, decimals by+  numeric value then scale — with no print-based fallback anywhere). All three are now structural;+  Java delegates to the generated `compareTo`.+- **Bash driver-layer audit** ([#714](https://github.com/CategoricalData/hydra/issues/714)):+  a prerequisite to the remaining #416 promotion. Six dead build scripts superseded by+  `transform-json-to-target.sh` are deleted, and the #608 oil-and-water and #540 header-idempotency+  regression harnesses are wired into `test-regressions.sh`.++- **Backward-compatibility and deprecation policy**+  ([#676](https://github.com/CategoricalData/hydra/issues/676)): adds the normative spec chapter defining+  what "compatible" means after 1.0 — the additivity calculus, the deprecation/rename mechanism, and+  enforcement. `LifecycleInfo.deprecatedSince` moves from defined-but-unused to populated on **32**+  kernel primitives slated for 0.18 deprecation, via a new `deprecatedSince` DSL helper.+- **Effect-sequencing contract specified and tested**+  ([#675](https://github.com/CategoricalData/hydra/issues/675)): `hydra.lib.effects` carries a sequencing+  contract — effects composed in a specified order, exactly once each, with `bind`'s continuation deferred+  until the prior effect has run. On the lazy Haskell host this falls out of the evaluation model; on the+  eight eager hosts it depended entirely on each hand-written interpreter. The obligations are now written+  into `effects.md` and backed by ordering-observation tests for `bind`/`foldList`/`mapList`/`mapOptional`.+- **Non-GC memory-discipline investigation**+  ([#678](https://github.com/CategoricalData/hydra/issues/678)): Hydra's data model says nothing about+  allocation, freeing, or ownership, which is what gates Swift, Rust, C++ and C as runtime hosts. This+  investigation delivers per-language verdicts plus leak-free proof-of-concept implementations — Rust+  (`Box` structural ownership), C++ (`unique_ptr` + arena) and C (arena), all ASan/LSan-clean on+  construct-and-drop of a recursive `Term` — and an airtight analysis of Swift's class-forcing requirement.+- **Build system promotion continues** ([#416](https://github.com/CategoricalData/hydra/issues/416)):+  adds `hydra.build.Registry`, which models per-language build identity as data (name / coder package /+  family) with per-script scope lists. `syncMatrix` and `langExpansion` are rewired onto it, and the+  hardcoded language lists in the test and bench scripts are retired in favour of a generated+  `languages.json`. Later in the cycle: `publishsets.reverseDepClosure` and+  `publishsets.requiresCoders` promote reverse-dependency propagation and per-package coder-loading+  into data, an `expected-libraries.json` artifact lets the Common Lisp and Emacs Lisp harnesses+  fail fast on a missing `hydra.lib`, and a host-independent `apply-assembly-plan.sh` executor+  (with a conformance test) takes over the Java `assemble-distribution` Step 0.+- **Serialization specification chapter**+  ([#674](https://github.com/CategoricalData/hydra/issues/674)): documents serializability, the+  encode/decode contract, and the round-trip law; `isSerializable` now forbids `void`+  ([#690](https://github.com/CategoricalData/hydra/issues/690)), and `hydra.lib.functions.absurd` is added+  as the void eliminator ([#684](https://github.com/CategoricalData/hydra/issues/684)).++### Bug fixes++- **Hoisting silently produced terms with free variables**+  ([#717](https://github.com/CategoricalData/hydra/issues/717)):+  `augmentBindingsWithNewFreeVars` returned a binding *unchanged* when a captured variable had no+  type in the context, yielding a top-level binding with free variables — a term valid before+  hoisting and invalid after, produced with no error. It is now total and fails loudly, per the+  kernel's fail-immediately rule.+- **TypeScript `div`/`mod` used truncating semantics**+  ([#677](https://github.com/CategoricalData/hydra/issues/677)): corrected to floor/Knuth division via+  shared bigint helpers, with an `Optional` codomain; the dead `maybeDiv`/`maybeMod` are deleted and an+  emitted-path test added.+- **Overlay lag behind the `null` -> `isEmpty` rename**+  ([#682](https://github.com/CategoricalData/hydra/issues/682)): the Java, Python, Scala, TypeScript and+  Lisp overlays each kept a stale spelling (`isEmpty_`, a half-renamed Python `null` impl, and Lisp+  camelCase where the coder emits snake_case), breaking generation until reconciled.+- **`check-haskell-def-completeness` could not resolve qualified assembly references**+  ([#683](https://github.com/CategoricalData/hydra/issues/683)), surfaced once the #703 cold-clone path+  began reaching the check.+- **Void-typed definitions leaked into DSL-ref generation**+  ([#684](https://github.com/CategoricalData/hydra/issues/684)): `absurd` and friends are now excluded+  across all hosts.+- **Scheme bootstrap loader gaps** ([#641](https://github.com/CategoricalData/hydra/issues/641)):+  missing `functions.scm`/`ordering.scm` in the native-lib load list, missing defaults in the def-module+  load list, and a guile-only import allowlist.+- **Bootstrap diff detail was swallowed** ([#671](https://github.com/CategoricalData/hydra/issues/671)):+  now persisted to `<run>/<path>.diff`, with `compare_output`'s return value no longer discarded.+  Separately, `compare_output` mis-derived the `src/main` vs `src/test` root per file+  ([#706](https://github.com/CategoricalData/hydra/issues/706)).+- **Nested duplicate output path** ([#664](https://github.com/CategoricalData/hydra/issues/664)) from+  `hydra-kernel` being hardcoded into `defaultOutput`.+- **Bootstrap codegen exceptions hid their stack traces**+  ([#707](https://github.com/CategoricalData/hydra/issues/707)) in `bootstrap.ts`.++### Release tooling++- `bin/check-release-env.sh` ([#704](https://github.com/CategoricalData/hydra/issues/704)) adds a+  publish-time toolchain preflight, after JDK- and twine-version problems cost real time at 0.17.5.+- The TypeScript head's node floor is lowered to `^18.0.0 || >=20.0.0`, the true vitest constraint+  ([#708](https://github.com/CategoricalData/hydra/issues/708)).+- Hydra does not create GitHub Releases; the detached `.asc` signature stays in `release-artifacts/`+  until [#441](https://github.com/CategoricalData/hydra/issues/441)+  ([#508](https://github.com/CategoricalData/hydra/issues/508)).++### Known issues++- The `hostOverrides` shim is pinned to `{java: local, python: local}` for the duration of the breaking+  batch, since the new kernel surface is by definition absent from published 0.17.5. It must be retired+  once 0.17.6 is visible in Maven Central and PyPI+  ([#508](https://github.com/CategoricalData/hydra/issues/508)).+- **`hydra-ext` does not ship to Maven Central for Java**, as in 0.17.4 and 0.17.5: the Java coder's+  visitor-pattern inner interface still collides with an enclosing type named `Visitor`+  ([#643](https://github.com/CategoricalData/hydra/issues/643)), so the package does not compile for+  that target. It publishes to Hackage and PyPI as usual.+- The breaking batch leaves three deliberate 0.18 tails, each separately tracked:+  `effects.pure` is retained provisionally pending a name decision+  ([#688](https://github.com/CategoricalData/hydra/issues/688)); the `printable` type class that would+  promote the print/parse convention into enforced dispatch awaits+  [#497](https://github.com/CategoricalData/hydra/issues/497); and the literal conversion lattice is+  gated on [#129](https://github.com/CategoricalData/hydra/issues/129) via+  [#689](https://github.com/CategoricalData/hydra/issues/689). Anticipated `TypeClassConstraint`+  variants remain open as [#686](https://github.com/CategoricalData/hydra/issues/686) — the `set`+  element type must stay orderable as variants are added.++---+ ## [0.17.5] - 2026-08-19  Point release on the 0.17.x line. Two language-surface changes lead: sum-type eliminators unify on
hydra-haskell.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.38.1.+-- This file has been generated from package.yaml by hpack version 0.39.1. -- -- see: https://github.com/sol/hpack  name:           hydra-haskell-version:        0.17.5+version:        0.17.6 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.5+    , hydra-kernel ==0.17.6     , scientific >=0.3.7 && <0.4   default-language: Haskell2010
src/main/haskell/Hydra/Dsl/Haskell/Environment.hs view
@@ -9,10 +9,11 @@ import qualified Hydra.Typed as Typed import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines) import qualified Data.Scientific as Sci+import Data.Void  -- | DSL constructor for hydra.haskell.environment.HaskellModuleMetadata-haskellModuleMetadata :: Typed.TypedTerm Bool -> Typed.TypedTerm Bool -> Typed.TypedTerm Bool -> Typed.TypedTerm Bool -> Typed.TypedTerm Environment.HaskellModuleMetadata-haskellModuleMetadata usesByteString usesInt usesMap usesSet =+haskellModuleMetadata :: Typed.TypedTerm Bool -> Typed.TypedTerm Bool -> Typed.TypedTerm Bool -> Typed.TypedTerm Bool -> Typed.TypedTerm Bool -> Typed.TypedTerm Environment.HaskellModuleMetadata+haskellModuleMetadata usesByteString usesInt usesMap usesSet usesVoid =     Typed.TypedTerm (Core.TermRecord (Core.Record {       Core.recordTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),       Core.recordFields = [@@ -27,7 +28,10 @@           Core.fieldTerm = (Typed.unTypedTerm usesMap)},         Core.Field {           Core.fieldName = (Core.Name "usesSet"),-          Core.fieldTerm = (Typed.unTypedTerm usesSet)}]}))+          Core.fieldTerm = (Typed.unTypedTerm usesSet)},+        Core.Field {+          Core.fieldName = (Core.Name "usesVoid"),+          Core.fieldTerm = (Typed.unTypedTerm usesVoid)}]}))  -- | DSL name token for hydra.haskell.environment.HaskellModuleMetadata haskellModuleMetadataHaskellModuleMetadata :: Typed.TypedName Environment.HaskellModuleMetadata@@ -69,6 +73,15 @@         Core.projectionFieldName = (Core.Name "usesSet")})),       Core.applicationArgument = (Typed.unTypedTerm x)})) +-- | DSL accessor for the usesVoid field of hydra.haskell.environment.HaskellModuleMetadata+haskellModuleMetadataUsesVoid :: Typed.TypedTerm Environment.HaskellModuleMetadata -> Typed.TypedTerm Bool+haskellModuleMetadataUsesVoid x =+    Typed.TypedTerm (Core.TermApplication (Core.Application {+      Core.applicationFunction = (Core.TermProject (Core.Projection {+        Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),+        Core.projectionFieldName = (Core.Name "usesVoid")})),+      Core.applicationArgument = (Typed.unTypedTerm x)}))+ -- | DSL updater for the usesByteString field of hydra.haskell.environment.HaskellModuleMetadata haskellModuleMetadataWithUsesByteString :: Typed.TypedTerm Environment.HaskellModuleMetadata -> Typed.TypedTerm Bool -> Typed.TypedTerm Environment.HaskellModuleMetadata haskellModuleMetadataWithUsesByteString original newVal =@@ -98,6 +111,13 @@             Core.applicationFunction = (Core.TermProject (Core.Projection {               Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),               Core.projectionFieldName = (Core.Name "usesSet")})),+            Core.applicationArgument = (Typed.unTypedTerm original)}))},+        Core.Field {+          Core.fieldName = (Core.Name "usesVoid"),+          Core.fieldTerm = (Core.TermApplication (Core.Application {+            Core.applicationFunction = (Core.TermProject (Core.Projection {+              Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),+              Core.projectionFieldName = (Core.Name "usesVoid")})),             Core.applicationArgument = (Typed.unTypedTerm original)}))}]}))  -- | DSL updater for the usesInt field of hydra.haskell.environment.HaskellModuleMetadata@@ -129,6 +149,13 @@             Core.applicationFunction = (Core.TermProject (Core.Projection {               Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),               Core.projectionFieldName = (Core.Name "usesSet")})),+            Core.applicationArgument = (Typed.unTypedTerm original)}))},+        Core.Field {+          Core.fieldName = (Core.Name "usesVoid"),+          Core.fieldTerm = (Core.TermApplication (Core.Application {+            Core.applicationFunction = (Core.TermProject (Core.Projection {+              Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),+              Core.projectionFieldName = (Core.Name "usesVoid")})),             Core.applicationArgument = (Typed.unTypedTerm original)}))}]}))  -- | DSL updater for the usesMap field of hydra.haskell.environment.HaskellModuleMetadata@@ -160,6 +187,13 @@             Core.applicationFunction = (Core.TermProject (Core.Projection {               Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),               Core.projectionFieldName = (Core.Name "usesSet")})),+            Core.applicationArgument = (Typed.unTypedTerm original)}))},+        Core.Field {+          Core.fieldName = (Core.Name "usesVoid"),+          Core.fieldTerm = (Core.TermApplication (Core.Application {+            Core.applicationFunction = (Core.TermProject (Core.Projection {+              Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),+              Core.projectionFieldName = (Core.Name "usesVoid")})),             Core.applicationArgument = (Typed.unTypedTerm original)}))}]}))  -- | DSL updater for the usesSet field of hydra.haskell.environment.HaskellModuleMetadata@@ -191,4 +225,49 @@             Core.applicationArgument = (Typed.unTypedTerm original)}))},         Core.Field {           Core.fieldName = (Core.Name "usesSet"),+          Core.fieldTerm = (Typed.unTypedTerm newVal)},+        Core.Field {+          Core.fieldName = (Core.Name "usesVoid"),+          Core.fieldTerm = (Core.TermApplication (Core.Application {+            Core.applicationFunction = (Core.TermProject (Core.Projection {+              Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),+              Core.projectionFieldName = (Core.Name "usesVoid")})),+            Core.applicationArgument = (Typed.unTypedTerm original)}))}]}))++-- | DSL updater for the usesVoid field of hydra.haskell.environment.HaskellModuleMetadata+haskellModuleMetadataWithUsesVoid :: Typed.TypedTerm Environment.HaskellModuleMetadata -> Typed.TypedTerm Bool -> Typed.TypedTerm Environment.HaskellModuleMetadata+haskellModuleMetadataWithUsesVoid original newVal =+    Typed.TypedTerm (Core.TermRecord (Core.Record {+      Core.recordTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),+      Core.recordFields = [+        Core.Field {+          Core.fieldName = (Core.Name "usesByteString"),+          Core.fieldTerm = (Core.TermApplication (Core.Application {+            Core.applicationFunction = (Core.TermProject (Core.Projection {+              Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),+              Core.projectionFieldName = (Core.Name "usesByteString")})),+            Core.applicationArgument = (Typed.unTypedTerm original)}))},+        Core.Field {+          Core.fieldName = (Core.Name "usesInt"),+          Core.fieldTerm = (Core.TermApplication (Core.Application {+            Core.applicationFunction = (Core.TermProject (Core.Projection {+              Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),+              Core.projectionFieldName = (Core.Name "usesInt")})),+            Core.applicationArgument = (Typed.unTypedTerm original)}))},+        Core.Field {+          Core.fieldName = (Core.Name "usesMap"),+          Core.fieldTerm = (Core.TermApplication (Core.Application {+            Core.applicationFunction = (Core.TermProject (Core.Projection {+              Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),+              Core.projectionFieldName = (Core.Name "usesMap")})),+            Core.applicationArgument = (Typed.unTypedTerm original)}))},+        Core.Field {+          Core.fieldName = (Core.Name "usesSet"),+          Core.fieldTerm = (Core.TermApplication (Core.Application {+            Core.applicationFunction = (Core.TermProject (Core.Projection {+              Core.projectionTypeName = (Core.Name "hydra.haskell.environment.HaskellModuleMetadata"),+              Core.projectionFieldName = (Core.Name "usesSet")})),+            Core.applicationArgument = (Typed.unTypedTerm original)}))},+        Core.Field {+          Core.fieldName = (Core.Name "usesVoid"),           Core.fieldTerm = (Typed.unTypedTerm newVal)}]}))
src/main/haskell/Hydra/Dsl/Haskell/Syntax.hs view
@@ -10,6 +10,7 @@ import qualified Hydra.Typed as Typed import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines) import qualified Data.Scientific as Sci+import Data.Void  -- | DSL constructor for hydra.haskell.syntax.Alternative alternative :: Typed.TypedTerm Syntax.Pattern -> Typed.TypedTerm Syntax.CaseRhs -> Typed.TypedTerm (Maybe Syntax.LocalBindings) -> Typed.TypedTerm Syntax.Alternative
src/main/haskell/Hydra/Haskell/Coder.hs view
@@ -69,6 +69,7 @@ import qualified Hydra.Variants as Variants import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines) import qualified Data.Scientific as Sci+import Data.Void import qualified Data.Map as M import qualified Data.Set as S @@ -141,7 +142,7 @@                                   malias = Pairs.second (Pairs.first triple)                                   hidden = Pairs.second triple                                   spec =-                                          Logic.ifElse (Lists.null hidden) Nothing (Just (Syntax.ImportSpecHiding (Lists.map (\n -> Syntax.NamedImportExport {+                                          Logic.ifElse (Lists.isEmpty hidden) Nothing (Just (Syntax.ImportSpecHiding (Lists.map (\n -> Syntax.NamedImportExport {                                             Syntax.namedImportExportModifier = Nothing,                                             Syntax.namedImportExportName = (Utils.simpleName n),                                             Syntax.namedImportExportSubspec = Nothing}) hidden)))@@ -166,7 +167,8 @@                             "sum",                             "unlines"])],                       [-                        (("Data.Scientific", (Just "Sci")), [])],+                        (("Data.Scientific", (Just "Sci")), []),+                        (("Data.Void", Nothing), [])],                       (condImport (Environment.haskellModuleMetadataUsesByteString meta) (("Data.ByteString", (Just "B")), [])),                       (condImport (Environment.haskellModuleMetadataUsesInt meta) (("Data.Int", (Just "I")), [])),                       (condImport (Environment.haskellModuleMetadataUsesMap meta) (("Data.Map", (Just "M")), [])),@@ -191,7 +193,8 @@       Environment.haskellModuleMetadataUsesByteString = False,       Environment.haskellModuleMetadataUsesInt = False,       Environment.haskellModuleMetadataUsesMap = False,-      Environment.haskellModuleMetadataUsesSet = False}+      Environment.haskellModuleMetadataUsesSet = False,+      Environment.haskellModuleMetadataUsesVoid = False}  -- | Encode a Hydra case statement as a Haskell case expression with a given scrutinee encodeCaseExpression :: Int -> Util.ModuleNames Syntax.ModuleName -> Core.CaseStatement -> Syntax.Expression -> t0 -> Graph.Graph -> Either Errors.Error Syntax.Expression@@ -204,7 +207,7 @@                   \fieldMap -> \field ->                     let fn = Core.caseAlternativeName field                         fun_ = Core.caseAlternativeHandler field-                        v0 = Strings.concat2 "v" (Literals.showInt32 depth)+                        v0 = Strings.concat2 "v" (Literals.printInt32 depth)                         raw =                                 Core.TermApplication (Core.Application {                                   Core.applicationFunction = fun_,@@ -256,7 +259,7 @@     case l of       Core.LiteralBinary v0 -> Right (Utils.hsapp (Utils.hsvar "Literals.base64ToBinary") (Utils.hslit (Syntax.LiteralString (Literals.binaryToBase64 v0))))       Core.LiteralBoolean v0 -> Right (Utils.hsvar (Logic.ifElse v0 "True" "False"))-      Core.LiteralDecimal v0 -> Right (Utils.hsapp (Utils.hsvar "Literals.stringToDecimal") (Utils.hslit (Syntax.LiteralString (Literals.showDecimal v0))))+      Core.LiteralDecimal v0 -> Right (Utils.hsapp (Utils.hsvar "Literals.stringToDecimal") (Utils.hslit (Syntax.LiteralString (Literals.printDecimal v0))))       Core.LiteralFloat v0 -> case v0 of         Core.FloatValueFloat32 v1 -> Right (Utils.hslit (Syntax.LiteralFloat v1))         Core.FloatValueFloat64 v1 -> Right (Utils.hslit (Syntax.LiteralDouble v1))@@ -345,7 +348,7 @@             Syntax.letExpressionInner = hinner})))))         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.TermMap v0 -> Logic.ifElse (Maps.isEmpty v0) (Right (Utils.hsvar "M.empty")) (nonemptyMap v0)         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,@@ -365,7 +368,7 @@           in (Eithers.bind (Eithers.mapList toFieldUpdate fields) (\updates -> Right (Syntax.ExpressionConstructRecord (Syntax.RecordExpression {             Syntax.recordExpressionName = typeName,             Syntax.recordExpressionFields = updates}))))-        Core.TermSet v0 -> Logic.ifElse (Sets.null v0) (Right (Utils.hsvar "S.empty")) (nonemptySet v0)+        Core.TermSet v0 -> Logic.ifElse (Sets.isEmpty v0) (Right (Utils.hsvar "S.empty")) (nonemptySet v0)         Core.TermTypeLambda v0 ->           let term1 = Core.typeLambdaBody v0           in (encode term1)@@ -500,7 +503,7 @@                         clsSet = Pairs.second mapEntry                         toPair = \c -> (name, c)                     in (Lists.map toPair (Sets.toList clsSet))-      in (Eithers.bind (adaptTypeToHaskellAndEncode namespaces typ cx g) (\htyp -> Logic.ifElse (Lists.null assertPairs) (Right htyp) (+      in (Eithers.bind (adaptTypeToHaskellAndEncode namespaces typ cx g) (\htyp -> Logic.ifElse (Lists.isEmpty assertPairs) (Right htyp) (         let encoded = Lists.map encodeAssertion assertPairs             hassert =                     Logic.ifElse (Equality.equal (Lists.length encoded) 1) (Optionals.withDefault (Syntax.ConstraintTuple encoded) (Lists.head encoded)) (Syntax.ConstraintTuple encoded)@@ -535,6 +538,7 @@         _ -> meta       Core.TypeMap _ -> setMetaUsesMap True meta       Core.TypeSet _ -> setMetaUsesSet True meta+      Core.TypeVoid -> setMetaUsesVoid True meta       _ -> meta  -- | Find type variables that require an Ord constraint (used in maps or sets)@@ -630,7 +634,8 @@       Environment.haskellModuleMetadataUsesByteString = b,       Environment.haskellModuleMetadataUsesInt = (Environment.haskellModuleMetadataUsesInt m),       Environment.haskellModuleMetadataUsesMap = (Environment.haskellModuleMetadataUsesMap m),-      Environment.haskellModuleMetadataUsesSet = (Environment.haskellModuleMetadataUsesSet m)}+      Environment.haskellModuleMetadataUsesSet = (Environment.haskellModuleMetadataUsesSet m),+      Environment.haskellModuleMetadataUsesVoid = (Environment.haskellModuleMetadataUsesVoid m)}  -- | Set the usesInt flag in Haskell module metadata setMetaUsesInt :: Bool -> Environment.HaskellModuleMetadata -> Environment.HaskellModuleMetadata@@ -639,7 +644,8 @@       Environment.haskellModuleMetadataUsesByteString = (Environment.haskellModuleMetadataUsesByteString m),       Environment.haskellModuleMetadataUsesInt = b,       Environment.haskellModuleMetadataUsesMap = (Environment.haskellModuleMetadataUsesMap m),-      Environment.haskellModuleMetadataUsesSet = (Environment.haskellModuleMetadataUsesSet m)}+      Environment.haskellModuleMetadataUsesSet = (Environment.haskellModuleMetadataUsesSet m),+      Environment.haskellModuleMetadataUsesVoid = (Environment.haskellModuleMetadataUsesVoid m)}  -- | Set the usesMap flag in Haskell module metadata setMetaUsesMap :: Bool -> Environment.HaskellModuleMetadata -> Environment.HaskellModuleMetadata@@ -648,7 +654,8 @@       Environment.haskellModuleMetadataUsesByteString = (Environment.haskellModuleMetadataUsesByteString m),       Environment.haskellModuleMetadataUsesInt = (Environment.haskellModuleMetadataUsesInt m),       Environment.haskellModuleMetadataUsesMap = b,-      Environment.haskellModuleMetadataUsesSet = (Environment.haskellModuleMetadataUsesSet m)}+      Environment.haskellModuleMetadataUsesSet = (Environment.haskellModuleMetadataUsesSet m),+      Environment.haskellModuleMetadataUsesVoid = (Environment.haskellModuleMetadataUsesVoid m)}  -- | Set the usesSet flag in Haskell module metadata setMetaUsesSet :: Bool -> Environment.HaskellModuleMetadata -> Environment.HaskellModuleMetadata@@ -657,8 +664,19 @@       Environment.haskellModuleMetadataUsesByteString = (Environment.haskellModuleMetadataUsesByteString m),       Environment.haskellModuleMetadataUsesInt = (Environment.haskellModuleMetadataUsesInt m),       Environment.haskellModuleMetadataUsesMap = (Environment.haskellModuleMetadataUsesMap m),-      Environment.haskellModuleMetadataUsesSet = b}+      Environment.haskellModuleMetadataUsesSet = b,+      Environment.haskellModuleMetadataUsesVoid = (Environment.haskellModuleMetadataUsesVoid m)} +-- | Set the usesVoid flag in Haskell module metadata+setMetaUsesVoid :: Bool -> Environment.HaskellModuleMetadata -> Environment.HaskellModuleMetadata+setMetaUsesVoid b m =+    Environment.HaskellModuleMetadata {+      Environment.haskellModuleMetadataUsesByteString = (Environment.haskellModuleMetadataUsesByteString m),+      Environment.haskellModuleMetadataUsesInt = (Environment.haskellModuleMetadataUsesInt m),+      Environment.haskellModuleMetadataUsesMap = (Environment.haskellModuleMetadataUsesMap m),+      Environment.haskellModuleMetadataUsesSet = (Environment.haskellModuleMetadataUsesSet m),+      Environment.haskellModuleMetadataUsesVoid = b}+ -- | Convert a Hydra term definition to a Haskell declaration with comments toDataDeclaration :: Util.ModuleNames Syntax.ModuleName -> Packaging.TermDefinition -> t0 -> Graph.Graph -> Either Errors.Error Syntax.Declaration toDataDeclaration namespaces def cx g =@@ -706,7 +724,7 @@                         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.match typ Nothing (\ts -> Core.typeSchemeConstraints ts)+                          schemeConstraints = Optionals.match typ Maps.empty (\ts -> Core.typeSchemeConstraints ts)                           schemeClasses = typeSchemeConstraintsToClassMap schemeConstraints                       in (Eithers.bind (Annotations.getTypeClasses cx g (Strip.removeTypesFromTerm term)) (\explicitClasses ->                         let combinedClasses = Maps.union schemeClasses explicitClasses@@ -890,13 +908,13 @@         in (Right decl)))  -- | Project type scheme constraints to a map of type variables to typeclass names-typeSchemeConstraintsToClassMap :: Ord t0 => (Maybe (M.Map t0 Core.TypeVariableConstraints) -> M.Map t0 (S.Set Core.Name))-typeSchemeConstraintsToClassMap maybeConstraints =+typeSchemeConstraintsToClassMap :: Ord t0 => (M.Map t0 Core.TypeVariableConstraints -> M.Map t0 (S.Set Core.Name))+typeSchemeConstraintsToClassMap constraints =        let constraintToName =               \tcc -> case tcc of                 Core.TypeClassConstraintSimple v0 -> Just v0-      in (Optionals.match maybeConstraints Maps.empty (\constraints -> Maps.map (\meta -> Sets.fromList (Optionals.givens (Lists.map constraintToName (Core.typeVariableConstraintsClasses meta)))) constraints))+      in (Maps.map (\meta -> Sets.fromList (Optionals.givens (Lists.map constraintToName (Sets.toList (Core.typeVariableConstraintsClasses meta))))) constraints)  -- | Whether to use the Hydra core import in generated modules useCoreImport :: Bool
src/main/haskell/Hydra/Haskell/Environment.hs view
@@ -7,6 +7,7 @@ import qualified Hydra.Core as Core import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines) import qualified Data.Scientific as Sci+import Data.Void  -- | Metadata used to determine which standard imports are needed in a generated Haskell module data HaskellModuleMetadata =@@ -18,7 +19,9 @@     -- | Whether the module uses Data.Map (M.Map, M.fromList, M.empty)     haskellModuleMetadataUsesMap :: Bool,     -- | Whether the module uses Data.Set (S.Set, S.fromList, S.empty)-    haskellModuleMetadataUsesSet :: Bool}+    haskellModuleMetadataUsesSet :: Bool,+    -- | Whether the module uses Data.Void (Void)+    haskellModuleMetadataUsesVoid :: Bool}   deriving (Eq, Ord, Read, Show)  _HaskellModuleMetadata = Core.Name "hydra.haskell.environment.HaskellModuleMetadata"@@ -30,3 +33,5 @@ _HaskellModuleMetadata_usesMap = Core.Name "usesMap"  _HaskellModuleMetadata_usesSet = Core.Name "usesSet"++_HaskellModuleMetadata_usesVoid = Core.Name "usesVoid"
src/main/haskell/Hydra/Haskell/Language.hs view
@@ -37,6 +37,7 @@ import qualified Hydra.Variants as Variants import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines) import qualified Data.Scientific as Sci+import Data.Void import qualified Data.Set as S  -- | Language constraints for Haskell
src/main/haskell/Hydra/Haskell/Operators.hs view
@@ -37,6 +37,7 @@ import qualified Hydra.Variants as Variants import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines) import qualified Data.Scientific as Sci+import Data.Void  -- | Logical AND operator (&&) andOp :: Ast.Op
src/main/haskell/Hydra/Haskell/Serde.hs view
@@ -53,6 +53,7 @@ import qualified Hydra.Variants as Variants import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines) import qualified Data.Scientific as Sci+import Data.Void  -- | Convert a pattern-matching alternative to an AST expression alternativeToExpr :: Syntax.Alternative -> Ast.Expr@@ -178,7 +179,7 @@                           derivCat = Lists.concat (Lists.map Syntax.unDerivingClause deriv)                           constructors = Serialization.orSep Serialization.halfBlockStyle (Lists.map constructorToExpr cons)                           derivingClause =-                                  Logic.ifElse (Lists.null derivCat) [] [+                                  Logic.ifElse (Lists.isEmpty derivCat) [] [                                     Serialization.spaceSep (Lists.cons (Serialization.cst "deriving") [                                       Serialization.parenList False (Lists.map nameToExpr derivCat)])]                           mainParts =@@ -323,11 +324,11 @@                     let raw = showFn v                     in (Logic.ifElse (Equality.equal raw "NaN") "(0/0)" (Logic.ifElse (Equality.equal raw "Infinity") "(1/0)" (Logic.ifElse (Equality.equal raw "-Infinity") "(-(1/0))" (parensIfNeg (Equality.equal (Optionals.withDefault 0 (Strings.charAt 0 raw)) 45) raw))))       in (Serialization.cst (case lit of-        Syntax.LiteralChar v0 -> Literals.printString (Literals.showUint16 v0)-        Syntax.LiteralDouble v0 -> showFloat (\v -> Literals.showFloat64 v) v0-        Syntax.LiteralFloat v0 -> showFloat (\v -> Literals.showFloat32 v) v0-        Syntax.LiteralInt v0 -> parensIfNeg (Ordering.lt v0 0) (Literals.showInt32 v0)-        Syntax.LiteralInteger v0 -> parensIfNeg (Ordering.lt v0 0) (Literals.showBigint v0)+        Syntax.LiteralChar v0 -> Literals.printString (Literals.printUint16 v0)+        Syntax.LiteralDouble v0 -> showFloat (\v -> Literals.printFloat64 v) v0+        Syntax.LiteralFloat v0 -> showFloat (\v -> Literals.printFloat32 v) v0+        Syntax.LiteralInt v0 -> parensIfNeg (Ordering.lt v0 0) (Literals.printInt32 v0)+        Syntax.LiteralInteger v0 -> parensIfNeg (Ordering.lt v0 0) (Literals.printBigint v0)         Syntax.LiteralString v0 -> Literals.printString v0))  -- | Convert a local binding to an AST expression@@ -362,7 +363,7 @@           headerLine = Optionals.match mh [] (\h -> [                 moduleHeadToExpr h])           declLines = Lists.map declarationToExpr decls-          importLines = Logic.ifElse (Lists.null imports) [] [+          importLines = Logic.ifElse (Lists.isEmpty imports) [] [                 Serialization.newlineSep (Lists.map importToExpr imports)]       in (Serialization.doubleNewlineSep (Lists.concat [         warning,
src/main/haskell/Hydra/Haskell/Syntax.hs view
@@ -7,6 +7,7 @@ import qualified Hydra.Core as Core import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines) import qualified Data.Scientific as Sci+import Data.Void  -- | A pattern-matching alternative data Alternative =
src/main/haskell/Hydra/Haskell/Testing.hs view
@@ -59,6 +59,7 @@ import qualified Hydra.Variants as Variants import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines) import qualified Data.Scientific as Sci+import Data.Void import qualified Data.Set as S  -- | Add namespaces from a set of names to existing namespaces
src/main/haskell/Hydra/Haskell/Utils.hs view
@@ -52,6 +52,7 @@ import qualified Hydra.Variants as Variants import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines) import qualified Data.Scientific as Sci+import Data.Void import qualified Data.Set as S  -- | Create an application pattern from a name and argument patterns@@ -234,7 +235,7 @@                 Syntax.qualifiedNameQualifiers = [],                 Syntax.qualifiedNameUnqualified = (Syntax.NamePart "")}))           app =-                  \l -> Optionals.withDefault dummyType (Optionals.map (\p -> Logic.ifElse (Lists.null (Pairs.second p)) (Pairs.first p) (Syntax.TypeApplication (Syntax.ApplicationType {+                  \l -> Optionals.withDefault dummyType (Optionals.map (\p -> Logic.ifElse (Lists.isEmpty (Pairs.second p)) (Pairs.first p) (Syntax.TypeApplication (Syntax.ApplicationType {                     Syntax.applicationTypeContext = (app (Pairs.second p)),                     Syntax.applicationTypeArgument = (Pairs.first p)}))) (Lists.uncons l))       in (app (Lists.reverse types))