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 +162/−0
- hydra-haskell.cabal +3/−3
- src/main/haskell/Hydra/Dsl/Haskell/Environment.hs +82/−3
- src/main/haskell/Hydra/Dsl/Haskell/Syntax.hs +1/−0
- src/main/haskell/Hydra/Haskell/Coder.hs +34/−16
- src/main/haskell/Hydra/Haskell/Environment.hs +6/−1
- src/main/haskell/Hydra/Haskell/Language.hs +1/−0
- src/main/haskell/Hydra/Haskell/Operators.hs +1/−0
- src/main/haskell/Hydra/Haskell/Serde.hs +8/−7
- src/main/haskell/Hydra/Haskell/Syntax.hs +1/−0
- src/main/haskell/Hydra/Haskell/Testing.hs +1/−0
- src/main/haskell/Hydra/Haskell/Utils.hs +2/−1
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))