diff --git a/.envrc b/.envrc new file mode 100644 index 000000000..3550a30f2 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index 0454beffc..24b0eddb4 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,7 @@ bower_components/ node_modules tmp/ .stack-work/ -output +# output tests/purs/docs/docs/ core-tests/full-core-docs.md tests/support/package-lock.json @@ -38,3 +38,8 @@ TAGS *.ps *.svg tests/purs/make/ +.direnv/ +/.pre-commit-config.yaml +/result* + +tests/purus/passing/**/cache-db.json \ No newline at end of file diff --git a/Architecture.md b/Architecture.md new file mode 100644 index 000000000..2b804ec05 --- /dev/null +++ b/Architecture.md @@ -0,0 +1,100 @@ +# Architecture + +This document contains an overview of the *current* architecture of our compiler pipeline. It is not meant to be exhaustive and is intended to serve as a guide for onboarding new developers / make the giant PRs more accessible. + + +## Step 1: Type Deduction/Synthesis (Language.PureScript.CoreFn.Desugar) + +During the research phase of this project, we determined that PIR (Plutus Intermediate Representation) should be our ultimate compilation target (with final compilation to UPLC handled by the PIR compiler). Because PIR is an explicitly typed language, and because the vanilla `CoreFn` AST is not explicitly typed, it is necessary to convert the `Language.PureScript.AST` AST into a typed variant. + +Because conversion to `CoreFn` occurs after the initial (vanilla PS) typechecker pass, we receive *most* expressions (but not all of them) annotated with the inferred or explicitly declared type. Desugared expressions or declarations involving type classes, however, are not ignored by the PS typechecker, but we require explicit annotations for explicit type class dictionaries and the functions that operate on them. + +This step consists of two main phases: + + - First, we traverse every *type* annotation in the vanilla PS `Module` that is the input to our conversion function and desugar constraint types to types that require explicit dictionary arguments. E.g. `Eq a => a -> (...)` becomes `Eq$Dict a -> a -> (...)`. + - Next, we deduce the types. Because top-level declarations are always explicitly typed, we proceed "top-down" from the top-level signature as far as we can, and switch to a "bottom-up" synthesis strategy in cases where the type cannot be determined by the top-level signature. + +Some notes: + + - We want to preserve quantifiers in this step. While some quantifiers can be eliminated during monomorphization, there is no guarantee that *all* of them will be eliminated (this is not a problem, because PIR supports universal quantification). This requires special machinery when performing type deduction on expressions that contain quantified polymorphic functions, since we must take care to ensure that the type variables "line up". + - We run our desugarer in the same monad stack as the PS TypeChecker, but this is largely a convenience (since it lets us use the PS machinery for binding local variables or type variables, etc). We should *never* perform type inference or make any calls to `unify`. + - The trickiest part of this is ensuring that type information for explicit type class dictionaries is introduced at the correct point. Again, type class dictionaries are not processed by the PS typechecker. + +## Step 2: Monomorphization & Inlining (Language.PureScript.CoreFn.Convert.Monomorphize) + +PureScript's implementation of Records employs Row Types. Moreover, PureScript supports *polymorphic* records, which are backed by *open rows* (e.g. `{a :: Foo | r}`). + +Records in PureScript (unlike in Haskell) are not just syntatic sugar for products - the order of fields in the record is *not* determined by the order of fields in the declaration or expression that introduces the record. *An* order can be established for any fully instantiated (i.e. closed - doesn't contain any type variables of kind `Row Type`) record types - we choose a lexicographic ordering to mirror PureScript's `RowToList` sorting but this is not essenital. + +We must, therefore, perform monomorphization on record types in order to transform Object Literals to literal products, transform record accessors into `case` analysis of the product that corresponds to the original record, and transform record updates into product updates. + +Because a single polymorphic record type may be instantiated to different concrete types at different places in the AST, we must also inline while we monomorphize. + +The general monomorphization procedure is as follows (not a full algorithm): + + 1. We traverse the AST until we reach an `App` node. + 2. We "peel" the App node and get an `(f,args)` where `f` is the "terminal" function expression and `args` is a list of the argument expressions to which it is applied. + 3. We check whether the type of `f` is already monomorphic. If it is, we make no change to the node. + 4. If `f` is not monomorphic, we strip the quantifiers and check whether we can specialize any bound type variables to a concrete type. E.g. if `f :: forall x. Tuple x x -> x -> Int` and the arguments are `[Tuple String String, String]`, we instantiate `x` to `String`. + 5. We recurse down the list of arguments. If we encounter an argument that is a free (term-level) variable that is *not* a Plutus builtin, we inline it, monomorphizing it to the concrete type of the argument if possible. + 6. We apply the (possibly monomorphized & inlined) argument to the function and procede to the next argument + until we run out of arguments to process. + 7. Finally, we re-quantify the type of `f` in the resulting expression. (It may contain free type variables of kind `Type`, which can be represented in PIR) + +The procedure for inlining is: + 1. We check whether the (term level) variable we aim to inline is locally scoped (i.e. qualified by source position) or globally scoped (e.g. qualified by module name). For now, we only attempt to inline globally scoped variables (...I forget why...) + 2. If the variable is globally scoped (i.e. is the name of a module-level declaration), we lookup the body of the declaration. There are two possibilities here: Either the declaration will be a single non-recursive binding, or it will be a member of a mutually recursive binding group. (PS compiler sorts these for us) + - If the declaration is non-recursive we "walk" its expression-body and monomorphize/inline the sub-expressions as necessary in order to properly assign the expression the type that it is to be monomorphized to. + - If the declaration the member of a recursive binding group, we pause inlining, walk the expression, and "collect" a `Map Name (Name,SourceType,Expr)` where the key is the original name of the expression, and the values are, respectively: The new "fresh" name to give to the monomorphized expression, the monomorphic type that we must assign the expression to, and the body of the declaration. We do this recursively until we have collected every member of the recursive binding group used in the target expression. Finally, we use that map to construct a *monomorphic* mutually recursive binding group (where the names are all fresh) and create a `Let`-binding for the monomorphized mutually recursive group. + +The implementation of the monomorphizer/inliner consists in a few key functions that call each other recursively. To make reviewing easier, here's a brief explanation of what the key functions do (or are supposed to do at any rate): + + - `monomorphizeA` is the entry point that checks whether the node is an `App`, peels the arguments and function parts from the `App`, and calls `handleFunction` on the function expression and its arguments. + - `handleFunction` branches depending on the function expression it is passed: + - If it is passed a `Var` qualified by modulename, and the modulename is `Builtin`, it just returns the variable (since Builtins cannot be meaningfully inlined). + - If it is passed an `Abs`, `handleFunction` tries to instantiate the type variables of the function type with corresponding concrete types of the arguments. If it succeeds, it subsitutes the concrete type in for the bound type variable in all sub-expressions and their types, then calls itself recursively on the body of the `Abs` until the type has been fully monomorphized. + - If it is passed a `Var` that is not a builtin, `handleFunction` attempts to inline the expression the `Var` refers to by calling `inlineAs` with the monomorphized type. If this succeeds, `handleFunction` calls itself recursively with the monomorphized/inlined expression. + - If it is passed anything else as the `f`, it checks whether the function type is monomorphic. + - If the `f` is monomorphic, it applies it to its arguments and returns the resulting expresion. + - If the `f` is not monomorphic, `handleFunction` throws an error. + - `inlineAs` performs inlining and implements the above algorithm. Note that `inlineAs` is passed a PS `Type` argument, which represents the type that the expression corresponding to the `Name` being inlined *should* have after inlining. + - `monomorphizeWithType` rewrites the type of an expression to match the supplied type and (much more importantly) rewrites the types of all sub-expressions to conform with the supplied type of the top-level expression. + +## Step 3: Object desugaring and final IR (Language.PureScript.CoreFn.[IR / DesugarObjects]) + +By the end of step 2, all polymorphic records have been monommorphized that can be monomorphized, but record-specific expression nodes (object updates/accessors/literals) still remain in the AST. In order to ensure that all "invalid" expressions and types have been desugared/eliminated prior to final PIR conversion, we define a restricted AST and `Type` type such that only expressions which can be converted into PIR can be represented - a kind of "parse-don't-validate" approach. (This AST is implemented with the `Bound` library.) + +At this stage, we construct a set of dictionaries for type and data constructors. When constructing these maps, we add an arbitrary number of constructors for anonymous products (i.e. tuples) to accommodate objects. Specifically, we add constructors for tuples of up to 100 (they look like `data $GEN.~Tuple1 a = $GEN.~Tuple1 a` etc). These dictionaries serve two purposes: + - We construct them in such a way that the SOP representation of the underlying data type is very explicit. I.e. for each *type* constructor, we construct an `[(Int,[Type])]` where the `Int` represents the corresponding data constructor's index in the data type, where this information (the constructor's index & arguments) is also available in the dictionary for each *data* constructor. (Due to the implementation of the PS AST, we need both of these dictionaries, even though in principle only the tycon dictionary is necessary) + - Embedding generated tuple types into these dictionaries allows us to treat desugared records as "normal" data types in the final compilation stage (i.e. they don't require any special handling). + +Conversion into this restricted IR AST is, aside from object expressions, very straightforward. Therefore, in the rest of this section I will explain the object desugaring process. + +### Object Literals + + 1. We extract a `Map PSString SourceType` from the object literal expression by inspecting the expressions in each field. + 2. We sort the fields lexicographically (which establishes the uniform order of the product that will be constructed). + 3. We generate "fake" names for the product's type and constructor. E.g. `$GEN.~Tuple2 a b`. + 4. We construct a specialized function type for the product's data constructor using the sorted arguments. + 5. We assemble the literal with the "fake" constructor function and the arguments. + +### Record Accessors + 1. We perform steps 1-4 of Object Literals conversion on the expression the accessor is being applied to, except we construct a Constructor `Binder` (a pattern), where the arguments are wildcard binders for every argument except the one that corresponds to the field being accessed. + 2. We use that pattern to construct a case expression that extracts the value corresponding to the field. + - This is kind of hard to explain without an example. Suppose we have `foo = {a: 1, b :: "yup"}` in `foo.b` + - That gets turned into (something like) `case foo of {$GEN.Tuple2 _ $HERE -> $HERE} ` + +### Record Updates + 1. Proceeds much like the accessor case, except we return a product in our case expression instead of returning a field. + - Using the above definition of `foo`, if we have `foo {b = "hello"}`, this turns into: + - `case foo of {$GEN.Tuple2 a _ -> $GEN.Tuple2 a "hello"}` + +## Step 4: Final Conversion to PIR (Language.PureScript.CoreFn.Convert.ToPIR) + +The final step of compilation is conceptually simple: We match on the constructors of our final IR and translate expressions (and the types they contain) into PIR `Term`s and `Type`s, using some machinery to generate fresh names when we need to construct a lambda (which should only happen when desugaring case expressions). + +NOTE: The *implementation* of case expressions is incredibly complex. At the moment we support matching on simple constructor patterns. Going forward, we ought to weak the final IR so that case expressions are presented in a form that makes it simpler to handle. + + + + diff --git a/cabal.project b/cabal.project index 51c7ecb87..29ca61bcc 100644 --- a/cabal.project +++ b/cabal.project @@ -1,2 +1,18 @@ +repository cardano-haskell-packages + url: https://input-output-hk.github.io/cardano-haskell-packages + secure: True + root-keys: + 3e0cce471cf09815f930210f7827266fd09045445d65923e6d0238a6cd15126f + 443abb7fb497a134c343faf52f0b659bd7999bc06b7f63fa76dc99d631f9bea1 + a86a1f6ce86c449c46666bda44268677abf29b5b2d2eb5ec7af903ec2f117a82 + bcec67e8e99cabfa7764d75ad9b158d72bfacf70ca1d0ec8bc6b4406d1bf8413 + c00aae8461a256275598500ea0e187588c35a5d5d7454fb57eac18d9edb86a56 + d4a35cd3121aa00d18544bb0ac01c3e1691d618f462c46129271bccf39f7e8ee + + packages: purescript.cabal + +-- HACK: plutus core cannot build without it, remove after bump. +constraints: + nothunks < 0.2 diff --git a/default.nix b/default.nix new file mode 100644 index 000000000..4ff7fc519 --- /dev/null +++ b/default.nix @@ -0,0 +1,31 @@ +{ + perSystem = { self', pkgs, config, ... }: + let + cardanoPackages = pkgs.fetchFromGitHub { + owner = "input-output-hk"; + repo = "cardano-haskell-packages"; + rev = "3df392af2a61d61bdac1afd9c3674f27d6aa8efc"; # branch: repo + hash = "sha256-vvm56KzA6jEkG3mvwh1LEdK4H4FKxeoOJNz90H8l8dQ="; + }; + + purus = config.libHaskell.mkPackage { + name = "purus"; + src = ./.; + + externalRepositories = { + "https://input-output-hk.github.io/cardano-haskell-packages" = cardanoPackages; + }; + }; + in + { + devShells.purus = purus.devShell; + + packages = { + purs = purus.packages."purescript:exe:purs"; + }; + + apps = { + purs.program = "${self'.packages.purs}/bin/purs"; + }; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..34d0f876a --- /dev/null +++ b/flake.lock @@ -0,0 +1,813 @@ +{ + "nodes": { + "HTTP": { + "flake": false, + "locked": { + "lastModified": 1451647621, + "narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=", + "owner": "phadej", + "repo": "HTTP", + "rev": "9bc0996d412fef1787449d841277ef663ad9a915", + "type": "github" + }, + "original": { + "owner": "phadej", + "repo": "HTTP", + "type": "github" + } + }, + "cabal-32": { + "flake": false, + "locked": { + "lastModified": 1603716527, + "narHash": "sha256-X0TFfdD4KZpwl0Zr6x+PLxUt/VyKQfX7ylXHdmZIL+w=", + "owner": "haskell", + "repo": "cabal", + "rev": "48bf10787e27364730dd37a42b603cee8d6af7ee", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.2", + "repo": "cabal", + "type": "github" + } + }, + "cabal-34": { + "flake": false, + "locked": { + "lastModified": 1645834128, + "narHash": "sha256-wG3d+dOt14z8+ydz4SL7pwGfe7SiimxcD/LOuPCV6xM=", + "owner": "haskell", + "repo": "cabal", + "rev": "5ff598c67f53f7c4f48e31d722ba37172230c462", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.4", + "repo": "cabal", + "type": "github" + } + }, + "cabal-36": { + "flake": false, + "locked": { + "lastModified": 1669081697, + "narHash": "sha256-I5or+V7LZvMxfbYgZATU4awzkicBwwok4mVoje+sGmU=", + "owner": "haskell", + "repo": "cabal", + "rev": "8fd619e33d34924a94e691c5fea2c42f0fc7f144", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.6", + "repo": "cabal", + "type": "github" + } + }, + "cardano-shell": { + "flake": false, + "locked": { + "lastModified": 1608537748, + "narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=", + "owner": "input-output-hk", + "repo": "cardano-shell", + "rev": "9392c75087cb9a3d453998f4230930dea3a95725", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-shell", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1672831974, + "narHash": "sha256-z9k3MfslLjWQfnjBtEtJZdq3H7kyi2kQtUThfTgdRk0=", + "owner": "input-output-hk", + "repo": "flake-compat", + "rev": "45f2638735f8cdc40fe302742b79f248d23eb368", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "hkm/gitlab-fix", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1706830856, + "narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "ghc-8.6.5-iohk": { + "flake": false, + "locked": { + "lastModified": 1600920045, + "narHash": "sha256-DO6kxJz248djebZLpSzTGD6s8WRpNI9BTwUeOf5RwY8=", + "owner": "input-output-hk", + "repo": "ghc", + "rev": "95713a6ecce4551240da7c96b6176f980af75cae", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "release/8.6.5-iohk", + "repo": "ghc", + "type": "github" + } + }, + "ghc98X": { + "flake": false, + "locked": { + "lastModified": 1696643148, + "narHash": "sha256-E02DfgISH7EvvNAu0BHiPvl1E5FGMDi0pWdNZtIBC9I=", + "ref": "ghc-9.8", + "rev": "443e870d977b1ab6fc05f47a9a17bc49296adbd6", + "revCount": 61642, + "submodules": true, + "type": "git", + "url": "https://gitlab.haskell.org/ghc/ghc" + }, + "original": { + "ref": "ghc-9.8", + "submodules": true, + "type": "git", + "url": "https://gitlab.haskell.org/ghc/ghc" + } + }, + "ghc99": { + "flake": false, + "locked": { + "lastModified": 1701580282, + "narHash": "sha256-drA01r3JrXnkKyzI+owMZGxX0JameMzjK0W5jJE/+V4=", + "ref": "refs/heads/master", + "rev": "f5eb0f2982e9cf27515e892c4bdf634bcfb28459", + "revCount": 62197, + "submodules": true, + "type": "git", + "url": "https://gitlab.haskell.org/ghc/ghc" + }, + "original": { + "submodules": true, + "type": "git", + "url": "https://gitlab.haskell.org/ghc/ghc" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "pre-commit-hooks-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703887061, + "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "hackage": { + "flake": false, + "locked": { + "lastModified": 1708215850, + "narHash": "sha256-jaxFHCObJ3uON5RNbeon795RmBG/SUFcFM77TAxx3hg=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "f5c26f4307f80cdc8ba7b762e0738c09d40a4685", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, + "haskell-nix": { + "inputs": { + "HTTP": "HTTP", + "cabal-32": "cabal-32", + "cabal-34": "cabal-34", + "cabal-36": "cabal-36", + "cardano-shell": "cardano-shell", + "flake-compat": "flake-compat", + "ghc-8.6.5-iohk": "ghc-8.6.5-iohk", + "ghc98X": "ghc98X", + "ghc99": "ghc99", + "hackage": "hackage", + "hls-1.10": "hls-1.10", + "hls-2.0": "hls-2.0", + "hls-2.2": "hls-2.2", + "hls-2.3": "hls-2.3", + "hls-2.4": "hls-2.4", + "hls-2.5": "hls-2.5", + "hls-2.6": "hls-2.6", + "hpc-coveralls": "hpc-coveralls", + "hydra": "hydra", + "iserv-proxy": "iserv-proxy", + "nix-tools-static": "nix-tools-static", + "nixpkgs": [ + "haskell-nix", + "nixpkgs-unstable" + ], + "nixpkgs-2003": "nixpkgs-2003", + "nixpkgs-2105": "nixpkgs-2105", + "nixpkgs-2111": "nixpkgs-2111", + "nixpkgs-2205": "nixpkgs-2205", + "nixpkgs-2211": "nixpkgs-2211", + "nixpkgs-2305": "nixpkgs-2305", + "nixpkgs-2311": "nixpkgs-2311", + "nixpkgs-unstable": "nixpkgs-unstable", + "old-ghc-nix": "old-ghc-nix", + "stackage": "stackage" + }, + "locked": { + "lastModified": 1708217408, + "narHash": "sha256-Ri9PXSAvg25bBvcJOCTsi6pRhaT8Wp37037KMfXYeOU=", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "2fb6466a23873e590ef96066ee18a75998830c7b", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "haskell.nix", + "type": "github" + } + }, + "hci-effects": { + "inputs": { + "flake-parts": [ + "flake-parts" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1704029560, + "narHash": "sha256-a4Iu7x1OP+uSYpqadOu8VCPY+MPF3+f6KIi+MAxlgyw=", + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "rev": "d5cbf433a6ae9cae05400189a8dbc6412a03ba16", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "type": "github" + } + }, + "hls-1.10": { + "flake": false, + "locked": { + "lastModified": 1680000865, + "narHash": "sha256-rc7iiUAcrHxwRM/s0ErEsSPxOR3u8t7DvFeWlMycWgo=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "b08691db779f7a35ff322b71e72a12f6e3376fd9", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "1.10.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.0": { + "flake": false, + "locked": { + "lastModified": 1687698105, + "narHash": "sha256-OHXlgRzs/kuJH8q7Sxh507H+0Rb8b7VOiPAjcY9sM1k=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "783905f211ac63edf982dd1889c671653327e441", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.0.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.2": { + "flake": false, + "locked": { + "lastModified": 1693064058, + "narHash": "sha256-8DGIyz5GjuCFmohY6Fa79hHA/p1iIqubfJUTGQElbNk=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "b30f4b6cf5822f3112c35d14a0cba51f3fe23b85", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.2.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.3": { + "flake": false, + "locked": { + "lastModified": 1695910642, + "narHash": "sha256-tR58doOs3DncFehHwCLczJgntyG/zlsSd7DgDgMPOkI=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "458ccdb55c9ea22cd5d13ec3051aaefb295321be", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.3.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.4": { + "flake": false, + "locked": { + "lastModified": 1699862708, + "narHash": "sha256-YHXSkdz53zd0fYGIYOgLt6HrA0eaRJi9mXVqDgmvrjk=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "54507ef7e85fa8e9d0eb9a669832a3287ffccd57", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.4.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.5": { + "flake": false, + "locked": { + "lastModified": 1701080174, + "narHash": "sha256-fyiR9TaHGJIIR0UmcCb73Xv9TJq3ht2ioxQ2mT7kVdc=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "27f8c3d3892e38edaef5bea3870161815c4d014c", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.5.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.6": { + "flake": false, + "locked": { + "lastModified": 1705325287, + "narHash": "sha256-+P87oLdlPyMw8Mgoul7HMWdEvWP/fNlo8jyNtwME8E8=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "6e0b342fa0327e628610f2711f8c3e4eaaa08b1e", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.6.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hpc-coveralls": { + "flake": false, + "locked": { + "lastModified": 1607498076, + "narHash": "sha256-8uqsEtivphgZWYeUo5RDUhp6bO9j2vaaProQxHBltQk=", + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "rev": "14df0f7d229f4cd2e79f8eabb1a740097fdfa430", + "type": "github" + }, + "original": { + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "type": "github" + } + }, + "hydra": { + "inputs": { + "nix": "nix", + "nixpkgs": [ + "haskell-nix", + "hydra", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1671755331, + "narHash": "sha256-hXsgJj0Cy0ZiCiYdW2OdBz5WmFyOMKuw4zyxKpgUKm4=", + "owner": "NixOS", + "repo": "hydra", + "rev": "f48f00ee6d5727ae3e488cbf9ce157460853fea8", + "type": "github" + }, + "original": { + "id": "hydra", + "type": "indirect" + } + }, + "iserv-proxy": { + "flake": false, + "locked": { + "lastModified": 1691634696, + "narHash": "sha256-MZH2NznKC/gbgBu8NgIibtSUZeJ00HTLJ0PlWKCBHb0=", + "ref": "hkm/remote-iserv", + "rev": "43a979272d9addc29fbffc2e8542c5d96e993d73", + "revCount": 14, + "type": "git", + "url": "https://gitlab.haskell.org/hamishmack/iserv-proxy.git" + }, + "original": { + "ref": "hkm/remote-iserv", + "type": "git", + "url": "https://gitlab.haskell.org/hamishmack/iserv-proxy.git" + } + }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "nix": { + "inputs": { + "lowdown-src": "lowdown-src", + "nixpkgs": "nixpkgs", + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1661606874, + "narHash": "sha256-9+rpYzI+SmxJn+EbYxjGv68Ucp22bdFUSy/4LkHkkDQ=", + "owner": "NixOS", + "repo": "nix", + "rev": "11e45768b34fdafdcf019ddbd337afa16127ff0f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "2.11.0", + "repo": "nix", + "type": "github" + } + }, + "nix-tools-static": { + "flake": false, + "locked": { + "lastModified": 1706266250, + "narHash": "sha256-9t+GRk3eO9muCtKdNAwBtNBZ5dH1xHcnS17WaQyftwA=", + "owner": "input-output-hk", + "repo": "haskell-nix-example", + "rev": "580cb6db546a7777dad3b9c0fa487a366c045c4e", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "nix", + "repo": "haskell-nix-example", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1657693803, + "narHash": "sha256-G++2CJ9u0E7NNTAi9n5G8TdDmGJXcIjkJ3NF8cetQB8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "365e1b3a859281cf11b94f87231adeabbdd878a2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.05-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2003": { + "locked": { + "lastModified": 1620055814, + "narHash": "sha256-8LEHoYSJiL901bTMVatq+rf8y7QtWuZhwwpKE2fyaRY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1db42b7fe3878f3f5f7a4f2dc210772fd080e205", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-20.03-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2105": { + "locked": { + "lastModified": 1659914493, + "narHash": "sha256-lkA5X3VNMKirvA+SUzvEhfA7XquWLci+CGi505YFAIs=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "022caabb5f2265ad4006c1fa5b1ebe69fb0c3faf", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2111": { + "locked": { + "lastModified": 1659446231, + "narHash": "sha256-hekabNdTdgR/iLsgce5TGWmfIDZ86qjPhxDg/8TlzhE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eabc38219184cc3e04a974fe31857d8e0eac098d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2205": { + "locked": { + "lastModified": 1685573264, + "narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "380be19fbd2d9079f677978361792cb25e8a3635", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-22.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2211": { + "locked": { + "lastModified": 1688392541, + "narHash": "sha256-lHrKvEkCPTUO+7tPfjIcb7Trk6k31rz18vkyqmkeJfY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ea4c80b39be4c09702b0cb3b42eab59e2ba4f24b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-22.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2305": { + "locked": { + "lastModified": 1701362232, + "narHash": "sha256-GVdzxL0lhEadqs3hfRLuj+L1OJFGiL/L7gCcelgBlsw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d2332963662edffacfddfad59ff4f709dde80ffe", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-23.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2311": { + "locked": { + "lastModified": 1701386440, + "narHash": "sha256-xI0uQ9E7JbmEy/v8kR9ZQan6389rHug+zOtZeZFiDJk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "293822e55ec1872f715a66d0eda9e592dc14419f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-23.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1694822471, + "narHash": "sha256-6fSDCj++lZVMZlyqOe9SIOL8tYSBz1bI8acwovRwoX8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "47585496bcb13fb72e4a90daeea2f434e2501998", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "47585496bcb13fb72e4a90daeea2f434e2501998", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1708276637, + "narHash": "sha256-+gICdImzDvxULC/+iqsmLsvwEv5LQuFglxn2fk/VyQM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ec841889d30aabad381acfa9529fe6045268bdbd", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "old-ghc-nix": { + "flake": false, + "locked": { + "lastModified": 1631092763, + "narHash": "sha256-sIKgO+z7tj4lw3u6oBZxqIhDrzSkvpHtv0Kki+lh9Fg=", + "owner": "angerman", + "repo": "old-ghc-nix", + "rev": "af48a7a7353e418119b6dfe3cd1463a657f342b8", + "type": "github" + }, + "original": { + "owner": "angerman", + "ref": "master", + "repo": "old-ghc-nix", + "type": "github" + } + }, + "pre-commit-hooks-nix": { + "inputs": { + "flake-compat": "flake-compat_2", + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1708018599, + "narHash": "sha256-M+Ng6+SePmA8g06CmUZWi1AjG2tFBX9WCXElBHEKnyM=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "haskell-nix": "haskell-nix", + "hci-effects": "hci-effects", + "nixpkgs": "nixpkgs_2", + "pre-commit-hooks-nix": "pre-commit-hooks-nix" + } + }, + "stackage": { + "flake": false, + "locked": { + "lastModified": 1708214991, + "narHash": "sha256-PCVnVqnBctf/qkpTBnBxwDHvfZaxXeq0bO98LxoKfhY=", + "owner": "input-output-hk", + "repo": "stackage.nix", + "rev": "0a279134ea4ae6269b93f76638c4ed9ccd9a496a", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "stackage.nix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..555cfe2e7 --- /dev/null +++ b/flake.nix @@ -0,0 +1,86 @@ +{ + description = "uplc-benchmark"; + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs"; + flake-parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; + pre-commit-hooks-nix = { + url = "github:cachix/pre-commit-hooks.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.nixpkgs-stable.follows = "nixpkgs"; + }; + hci-effects = { + url = "github:hercules-ci/hercules-ci-effects"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-parts.follows = "flake-parts"; + }; + haskell-nix = { + url = "github:input-output-hk/haskell.nix"; + }; + }; + outputs = inputs: + let + flakeModules = { + haskell = ./nix/haskell; + utils = ./nix/utils; + }; + in + inputs.flake-parts.lib.mkFlake { inherit inputs; } ({ self, ... }: { + imports = [ + inputs.pre-commit-hooks-nix.flakeModule + inputs.hci-effects.flakeModule + ./. + ] ++ (builtins.attrValues flakeModules); + + # `nix flake show --impure` hack + systems = + if builtins.hasAttr "currentSystem" builtins + then [ builtins.currentSystem ] + else inputs.nixpkgs.lib.systems.flakeExposed; + + herculesCI.ciSystems = [ "x86_64-linux" ]; + + flake.flakeModules = flakeModules; + + perSystem = + { config + , pkgs + , lib + , system + , self' + , ... + }: { + _module.args.pkgs = import self.inputs.nixpkgs { + inherit system; + config.allowBroken = true; + }; + + pre-commit.settings = { + hooks = { + deadnix.enable = true; + # TODO: Enable in separate PR, causes mass changes. + # fourmolu.enable = true; + nixpkgs-fmt.enable = true; + }; + + tools = { + fourmolu = lib.mkForce (pkgs.callPackage ./nix/fourmolu { + mkHaskellPackage = config.libHaskell.mkPackage; + }); + }; + }; + + devShells = { + default = pkgs.mkShell { + shellHook = config.pre-commit.installationScript; + + inputsFrom = [ + self'.devShells.purus + ]; + }; + }; + }; + }); +} diff --git a/fourmolu.yaml b/fourmolu.yaml new file mode 100644 index 000000000..ed2de01bd --- /dev/null +++ b/fourmolu.yaml @@ -0,0 +1,8 @@ +indentation: 2 +comma-style: leading +record-brace-space: true +indent-wheres: true +diff-friendly-import-export: true +respectful: true +haddock-style: multi-line +newlines-between-decls: 1 diff --git a/hie.yaml b/hie.yaml new file mode 100644 index 000000000..397604162 --- /dev/null +++ b/hie.yaml @@ -0,0 +1,43 @@ +cradle: + cabal: + - path: "src" + component: "lib:purescript" + + - path: "app/Main.hs" + component: "purescript:exe:purs" + + - path: "app/Command/Bundle.hs" + component: "purescript:exe:purs" + + - path: "app/Command/Compile.hs" + component: "purescript:exe:purs" + + - path: "app/Command/Docs.hs" + component: "purescript:exe:purs" + + - path: "app/Command/Docs/Html.hs" + component: "purescript:exe:purs" + + - path: "app/Command/Docs/Markdown.hs" + component: "purescript:exe:purs" + + - path: "app/Command/Graph.hs" + component: "purescript:exe:purs" + + - path: "app/Command/Hierarchy.hs" + component: "purescript:exe:purs" + + - path: "app/Command/Ide.hs" + component: "purescript:exe:purs" + + - path: "app/Command/Publish.hs" + component: "purescript:exe:purs" + + - path: "app/Command/REPL.hs" + component: "purescript:exe:purs" + + - path: "app/Version.hs" + component: "purescript:exe:purs" + + - path: "tests" + component: "purescript:test:tests" diff --git a/nix/fourmolu/default.nix b/nix/fourmolu/default.nix new file mode 100644 index 000000000..954cbfaa0 --- /dev/null +++ b/nix/fourmolu/default.nix @@ -0,0 +1,13 @@ +{ mkHaskellPackage +, fetchFromGitHub +}: + +(mkHaskellPackage { + name = "fourmolu"; + src = fetchFromGitHub { + owner = "fourmolu"; + repo = "fourmolu"; + rev = "v0.13.1.0"; + hash = "sha256-abUK9KdvVI7di84X/L3vHZM97pOsciyx503aDjUnoc4="; + }; +}).packages."fourmolu:exe:fourmolu" diff --git a/nix/haskell/default.nix b/nix/haskell/default.nix new file mode 100644 index 000000000..fc5dd7400 --- /dev/null +++ b/nix/haskell/default.nix @@ -0,0 +1,36 @@ +{ self +, lib +, flake-parts-lib +, ... +}: +let + inherit (flake-parts-lib) mkPerSystemOption; + inherit (lib) types mkOption; +in +{ + options = { + perSystem = mkPerSystemOption ({ config, system, pkgs, ... }: { + options = { + libHaskell = mkOption { + type = types.anything; + default = { }; + }; + }; + + config = + let + mkHaskellPackage = pkgs.callPackage ./lib.nix { + inherit lib system; + haskellNixNixpkgs = self.inputs.haskell-nix.inputs.nixpkgs; + haskellNixOverlay = self.inputs.haskell-nix.overlay; + }; + + in + { + libHaskell = { + mkPackage = mkHaskellPackage; + }; + }; + }); + }; +} diff --git a/nix/haskell/lib.nix b/nix/haskell/lib.nix new file mode 100644 index 000000000..2dcbb208b --- /dev/null +++ b/nix/haskell/lib.nix @@ -0,0 +1,91 @@ +{ lib +, fetchFromGitHub + # e.g. "x86_64-linux" +, system # : string +, haskellNixNixpkgs # : nixpkgs +, haskellNixOverlay # : overlay +}: + +let + iohk-nix = fetchFromGitHub { + owner = "input-output-hk"; + repo = "iohk-nix"; + rev = "4848df60660e21fbb3fe157d996a8bac0a9cf2d6"; + hash = "sha256-ediFkDOBP7yVquw1XtHiYfuXKoEnvKGjTIAk9mC6qxo="; + }; + + pkgs = import haskellNixNixpkgs { + inherit system; + overlays = [ + (import "${iohk-nix}/overlays/crypto") + haskellNixOverlay + ]; + }; +in + +{ name # : string +, src # : path +, ghcVersion ? "ghc928" # : string +, haskellModules ? [ ] +, externalDependencies ? [ ] +, externalRepositories ? { } +}: +let + mkHackage = pkgs.callPackage ./mk-hackage.nix { + nix-tools = pkgs.haskell-nix.nix-tools-set { + compiler-nix-name = ghcVersion; + }; + }; + + # This looks like a noop but without it haskell.nix throws a runtime + # error about `pkgs` attribute not being present which is nonsense + # https://input-output-hk.github.io/haskell.nix/reference/library.html?highlight=cabalProject#modules + fixedHaskellModules = map (m: args @ { ... }: m args) haskellModules; + + flatExternalDependencies = + lib.lists.concatMap + (dep: [ (dep.passthru or { }).src or dep ] ++ + (flatExternalDependencies (dep.passthru or { }).externalDependencies or [ ])); + + flattenedExternalDependencies = flatExternalDependencies externalDependencies; + + customHackages = mkHackage { + srcs = map toString flattenedExternalDependencies; + inherit name; + }; + + project = pkgs.haskell-nix.cabalProject' { + inherit src; + name = name; + + compiler-nix-name = ghcVersion; + inputMap = lib.mapAttrs (_: toString) externalRepositories; + + modules = customHackages.modules ++ fixedHaskellModules; + inherit (customHackages) extra-hackages extra-hackage-tarballs; + + shell = { + withHoogle = true; + exactDeps = true; + + tools = { + cabal = { }; + haskell-language-server = { }; + }; + }; + }; + + projectFlake = project.flake { }; + + augmentedPackages = builtins.mapAttrs + (_: package: + package // { + passthru = (package.passthru or { }) // { + inherit src externalDependencies; + }; + }) + (projectFlake.packages or { }); +in +projectFlake // { + packages = augmentedPackages; +} diff --git a/nix/haskell/mk-hackage.nix b/nix/haskell/mk-hackage.nix new file mode 100644 index 000000000..fc89862f6 --- /dev/null +++ b/nix/haskell/mk-hackage.nix @@ -0,0 +1,134 @@ +# Adapted from https://github.com/mlabs-haskell/mlabs-tooling.nix/blob/cd0cf0d29f17980befe384248c16937589912c69/mk-hackage.nix + +{ gzip +, runCommand +, lib +, nix-tools +}: +let + mkPackageSpec = src: + with lib; + let + cabalFiles = concatLists (mapAttrsToList + (name: type: if type == "regular" && hasSuffix ".cabal" name then [ name ] else [ ]) + (builtins.readDir src)); + + cabalPath = + if length cabalFiles == 1 + then src + "/${builtins.head cabalFiles}" + else builtins.abort "Could not find unique file with .cabal suffix in source: ${src}"; + cabalFile = builtins.readFile cabalPath; + parse = field: + let + lines = filter (s: builtins.match "^${field} *:.*$" (toLower s) != null) (splitString "\n" cabalFile); + line = + if lines != [ ] + then head lines + else builtins.abort "Could not find line with prefix ''${field}:' in ${cabalPath}"; + in + replaceStrings [ " " ] [ "" ] (head (tail (splitString ":" line))); + pname = parse "name"; + version = parse "version"; + in + { inherit src pname version; }; + + mkHackageDir = { pname, version, src }: + runCommand "${pname}-${version}-hackage" + { } '' + set -e + mkdir -p $out/${pname}/${version} + md5=11111111111111111111111111111111 + sha256=1111111111111111111111111111111111111111111111111111111111111111 + length=1 + cat < $out/"${pname}"/"${version}"/package.json + { + "signatures" : [], + "signed" : { + "_type" : "Targets", + "expires" : null, + "targets" : { + "/package/${pname}-${version}.tar.gz" : { + "hashes" : { + "md5" : "$md5", + "sha256" : "$sha256" + }, + "length" : $length + } + }, + "version" : 0 + } + } + EOF + cp ${src}/*.cabal $out/"${pname}"/"${version}"/ + ''; + + mkHackageTarballFromDirs = name: hackageDirs: + runCommand "${name}-hackage-index.tar.gz" { } '' + mkdir hackage + ${builtins.concatStringsSep "" (map (dir: '' + echo ${dir} + ln -sf ${dir}/* hackage/ + '') hackageDirs)} + cd hackage + tar --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2009-01-01' -hczvf $out */*/* + ''; + + mkHackageTarball = name: pkg-specs: + mkHackageTarballFromDirs name (map mkHackageDir pkg-specs); + + mkHackageNix = name: hackageTarball: + runCommand "${name}-hackage-nix" + { + nativeBuildInputs = [ + gzip + nix-tools + ]; + } '' + set -e + export LC_CTYPE=C.UTF-8 + export LC_ALL=C.UTF-8 + export LANG=C.UTF-8 + cp ${hackageTarball} 01-index.tar.gz + gunzip 01-index.tar.gz + hackage-to-nix $out 01-index.tar "https://mkHackageNix/" + ''; + + mkModule = extraHackagePackages: { + packages = lib.listToAttrs (map + (spec: { + name = spec.pname; + value = { + inherit (spec) src; + }; + }) + extraHackagePackages); + }; + + mkHackageFromSpec = name: extraHackagePackages: rec { + extra-hackage-tarball = mkHackageTarball name extraHackagePackages; + extra-hackage = mkHackageNix name extra-hackage-tarball; + module = mkModule extraHackagePackages; + }; + +in +{ srcs # : [string] +, name # : string +}: + +if builtins.length srcs == 0 +then { + modules = [ ]; + extra-hackage-tarballs = { }; + extra-hackages = [ ]; +} +else + let + hackage = mkHackageFromSpec name (map mkPackageSpec srcs); + in + { + modules = [ hackage.module ]; + extra-hackage-tarballs = { + "${name}-hackage-tarball" = hackage.extra-hackage-tarball; + }; + extra-hackages = [ (import hackage.extra-hackage) ]; + } diff --git a/nix/utils/default.nix b/nix/utils/default.nix new file mode 100644 index 000000000..851ab543a --- /dev/null +++ b/nix/utils/default.nix @@ -0,0 +1,22 @@ +{ lib +, flake-parts-lib +, ... +}: +let + inherit (flake-parts-lib) mkPerSystemOption; + inherit (lib) types mkOption; +in +{ + options = { + perSystem = mkPerSystemOption ({ config, pkgs, ... }: { + options = { + libUtils = mkOption { + type = types.anything; + default = { }; + }; + }; + + config.libUtils = pkgs.callPackage ./lib.nix { }; + }); + }; +} diff --git a/nix/utils/lib.nix b/nix/utils/lib.nix new file mode 100644 index 000000000..c5b2f51b4 --- /dev/null +++ b/nix/utils/lib.nix @@ -0,0 +1,39 @@ +{ stdenv +, lib +}: + +let + applyPatches = args @ { patches, ... }: stdenv.mkDerivation ({ + inherit patches; + + dontConfigure = true; + dontBuild = true; + + installPhase = '' + mkdir -p "$out" + cp -r * "$out" + ''; + + dontFixup = true; + } // args); + + mkFlag = flag: value: "--${flag}=${value}"; + + mkFlags = flag: values: builtins.concatStringsSep " " (map (mkFlag flag) values); + + mkCli = args: + builtins.concatStringsSep " " + (lib.attrsets.mapAttrsToList + (flag: value: + if builtins.isList value + then mkFlags flag value + else if builtins.isBool value then (if value then "--${flag}" else "") + else mkFlag flag "${value}" + ) + args); + + withNameAttr = f: name: args: f (args // { inherit name; }); +in +{ + inherit applyPatches mkCli withNameAttr; +} diff --git a/npm-package/.gitignore b/npm-package/.gitignore deleted file mode 100644 index 059fb4c54..000000000 --- a/npm-package/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -purs.bin -package-lock.json diff --git a/npm-package/LICENSE b/npm-package/LICENSE deleted file mode 100644 index d99869e6a..000000000 --- a/npm-package/LICENSE +++ /dev/null @@ -1,6 +0,0 @@ -ISC License (ISC) -Copyright 2017 - 2019 Watanabe Shinnosuke - -Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/npm-package/README.md b/npm-package/README.md deleted file mode 100644 index de5495598..000000000 --- a/npm-package/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# PureScript npm package - -[![npm version](http://img.shields.io/npm/v/purescript.svg)](https://www.npmjs.com/package/purescript) -[![Build Status](https://travis-ci.org/purescript-contrib/node-purescript.svg?branch=master)](https://travis-ci.org/purescript-contrib/node-purescript) - -[PureScript](https://github.com/purescript/purescript) binary wrapper that makes it seamlessly available via [npm](https://www.npmjs.com/) - -## Prerequisites - -This package makes maximum use of `postinstall` [script](https://docs.npmjs.com/misc/scripts), so please make sure that [`ignore-scripts` npm-config](https://docs.npmjs.com/misc/config#ignore-scripts) is not enabled before installation. - -```console -$ npm config get ignore-scripts -false -``` - -## Installation - -[Use](https://docs.npmjs.com/cli/install) [npm](https://docs.npmjs.com/about-npm/). - -``` -npm install purescript -``` - -Once the command above is executed, - -__1.__ First, it checks if a PureScript binary has been already cached, and restores that if available. - -__2.__ The second plan: if no cache is available, it downloads a prebuilt binary from [the PureScript release page](https://github.com/purescript/purescript/releases). - -__3.__ The last resort: if no prebuilt binary is provided for your platform or the downloaded binary doesn't work correctly, it downloads [the PureScript source code](https://github.com/purescript/purescript/tree/master) and compile it with [Stack](https://docs.haskellstack.org/). - -## API - -### `require('purescript')` - -Type: `string` - -An absolute path to the installed PureScript binary, which can be used with [`child_process`](https://nodejs.org/api/child_process.html) functions. - -```javascript -const {execFile} = require('child_process'); -const purs = require('purescript'); //=> '/Users/you/example/node_modules/purescript/purs.bin' - -execFile(purs, ['compile', 'input.purs', '--output', 'output.purs'], () => { - console.log('Compiled.'); -}); -``` - -## CLI - -You can use it via CLI by installing it [globally](https://docs.npmjs.com/files/folders#global-installation). - -``` -npm install --global purescript - -purs --help -``` - -## License - -[ISC License](./LICENSE) © 2017 - 2019 Watanabe Shinnosuke diff --git a/npm-package/index.js b/npm-package/index.js deleted file mode 100644 index b4fec3cf5..000000000 --- a/npm-package/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require.resolve('./purs.bin'); diff --git a/npm-package/package.json b/npm-package/package.json deleted file mode 100644 index b24866695..000000000 --- a/npm-package/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "purescript", - "version": "0.15.13", - "license": "ISC", - "description": "PureScript wrapper that makes it available as a local dependency", - "author": { - "name": "Watanabe Shinnosuke", - "url": "http://github.com/shinnn" - }, - "files": [ - "index.js", - "purs.bin" - ], - "bin": { - "purs": "purs.bin" - }, - "dependencies": { - "purescript-installer": "^0.3.5" - }, - "homepage": "https://github.com/purescript/purescript", - "repository": { - "type": "git", - "url": "git+https://github.com/purescript/purescript.git" - }, - "bugs": { - "url": "https://github.com/purescript/npm-installer/issues" - }, - "keywords": [ - "cli", - "build", - "install", - "installation", - "fallback", - "purs", - "purescript", - "haskell", - "language", - "compile", - "compiler", - "bin", - "binary", - "wrapper" - ], - "scripts": { - "prepublishOnly": "node -e \"require('fs').copyFileSync('purs.bin.placeholder', 'purs.bin');\"", - "postinstall": "install-purescript --purs-ver=0.15.13", - "test": "echo 'Error: no test specified' && exit 1" - } -} diff --git a/npm-package/purs.bin.placeholder b/npm-package/purs.bin.placeholder deleted file mode 100755 index ca25a635f..000000000 --- a/npm-package/purs.bin.placeholder +++ /dev/null @@ -1,7 +0,0 @@ -# This is a placeholder file of a PureScript binary installed with npm. If you -# see this file, that means the installation has failed and the placeholder has -# not been replaced with a valid binary. Try installing the `purescript` npm -# package again. - -echo >&2 "purescript npm installer: installation failed; please try installing again" -exit 1 diff --git a/purescript.cabal b/purescript.cabal index a608c61ca..93be2f0c6 100644 --- a/purescript.cabal +++ b/purescript.cabal @@ -1,4 +1,4 @@ -cabal-version: 2.4 +cabal-version: 3.0 name: purescript -- Note: don't add prerelease identifiers here! Add them in app/Version.hs and npm-package/package.json instead. @@ -34,7 +34,7 @@ extra-source-files: tests/support/pscide/src/**/*.purs tests/support/pscide/src/**/*.js tests/support/pscide/src/**/*.fail - stack.yaml + -- stack.yaml README.md INSTALL.md CONTRIBUTORS.md @@ -86,6 +86,9 @@ common defaults -Wno-missing-export-lists -Wno-missing-kind-signatures -Wno-partial-fields + + -- TODO: Remove + -O0 default-language: Haskell2010 default-extensions: BangPatterns @@ -119,7 +122,7 @@ common defaults TypeFamilies ViewPatterns build-tool-depends: - happy:happy ==1.20.0 + happy:happy ^>= 1.20.0 build-depends: -- NOTE: Please do not edit these version constraints manually. They are -- deliberately made narrow because changing the dependency versions in @@ -155,15 +158,18 @@ common defaults -- specific version. aeson >=2.0.3.0 && <2.1, aeson-better-errors >=0.9.1.1 && <0.10, + aeson-diff, ansi-terminal >=0.11.3 && <0.12, array >=0.5.4.0 && <0.6, - base >=4.16.2.0 && <4.17, + base >=4.16.2.0 && <4.18, blaze-html >=0.9.1.2 && <0.10, bower-json >=1.1.0.0 && <1.2, boxes >=0.1.5 && <0.2, + bound, bytestring >=0.11.3.1 && <0.12, Cabal >=3.6.3.0 && <3.7, cborg >=0.2.7.0 && <0.3, + deriving-compat, serialise >=0.2.5.0 && <0.3, cheapskate >=0.1.1.2 && <0.2, clock >=0.8.3 && <0.9, @@ -179,7 +185,8 @@ common defaults Glob >=0.10.2 && <0.11, haskeline >=0.8.2 && <0.9, language-javascript ==0.7.0.0, - lens >=5.1.1 && <5.2, + lens >=5.1.1 && <5.3, + lens-indexed-plated, lifted-async >=0.10.2.2 && <0.11, lifted-base >=0.2.3.12 && <0.3, memory >=0.17.0 && <0.18, @@ -191,6 +198,8 @@ common defaults parsec >=3.1.15.0 && <3.2, pattern-arrows >=0.0.2 && <0.1, process ==1.6.13.1, + pretty-simple, + prettyprinter, protolude >=0.3.1 && <0.4, regex-tdfa >=1.3.1.2 && <1.4, safe >=0.3.19 && <0.4, @@ -200,15 +209,20 @@ common defaults sourcemap >=0.1.7 && <0.2, stm >=2.5.0.2 && <2.6, stringsearch >=0.3.6.6 && <0.4, + tasty, + tasty-hunit, template-haskell >=2.18.0.0 && <2.19, - text >=1.2.5.0 && <1.3, + text >=1.2.5.0 && <2.3, + th-abstraction, these >=1.1.1.1 && <1.2, time >=1.11.1.1 && <1.12, transformers >=0.5.6.2 && <0.6, transformers-base >=0.4.6 && <0.5, utf8-string >=1.0.2 && <1.1, vector >=0.12.3.1 && <0.13, - witherable >=0.4.2 && <0.5 + witherable >=0.4.2 && <0.5, + plutus-core, + plutus-core:plutus-ir library import: defaults @@ -230,23 +244,38 @@ library Language.PureScript.AST.Utils Language.PureScript.Bundle Language.PureScript.CodeGen - Language.PureScript.CodeGen.JS - Language.PureScript.CodeGen.JS.Common - Language.PureScript.CodeGen.JS.Printer + Language.PureScript.CodeGen.UPLC Language.PureScript.Constants.Libs + Language.PureScript.Constants.Purus + Language.PureScript.Constants.PLC + Language.PureScript.Constants.PLC.TH Language.PureScript.CoreFn Language.PureScript.CoreFn.Ann Language.PureScript.CoreFn.Binders + Language.PureScript.CoreFn.Convert + Language.PureScript.CoreFn.Convert.Monomorphize + Language.PureScript.CoreFn.Convert.Monomorphize.Utils + Language.PureScript.CoreFn.Convert.MonomorphizeV2 + Language.PureScript.CoreFn.Convert.DesugarObjects + Language.PureScript.CoreFn.Convert.DesugarCore + Language.PureScript.CoreFn.Convert.IR + Language.PureScript.CoreFn.Convert.ToPIR Language.PureScript.CoreFn.CSE Language.PureScript.CoreFn.Desugar + Language.PureScript.CoreFn.Desugar.Utils Language.PureScript.CoreFn.Expr Language.PureScript.CoreFn.FromJSON - Language.PureScript.CoreFn.Laziness Language.PureScript.CoreFn.Meta Language.PureScript.CoreFn.Module Language.PureScript.CoreFn.Optimizer + Language.PureScript.CoreFn.Pretty + Language.PureScript.CoreFn.Pretty.Common + Language.PureScript.CoreFn.Pretty.Expr + Language.PureScript.CoreFn.Pretty.Types Language.PureScript.CoreFn.ToJSON Language.PureScript.CoreFn.Traversals + Language.PureScript.CoreFn.TypeLike + Language.PureScript.CoreFn.Utils Language.PureScript.CoreImp Language.PureScript.CoreImp.AST Language.PureScript.CoreImp.Module @@ -406,13 +435,35 @@ executable purs exceptions >=0.10.4 && <0.11, network >=3.1.2.7 && <3.2, optparse-applicative >=0.17.0.0 && <0.18, - purescript + purescript, + purs-lib if flag(release) cpp-options: -DRELEASE else build-depends: gitrev >=1.2.0 && <1.4 other-modules: + Paths_purescript + autogen-modules: + Paths_purescript + +library purs-lib + import: defaults + hs-source-dirs: purs-lib + -- main-is: Main.hs + ghc-options: -fno-warn-unused-do-bind -threaded -rtsopts -with-rtsopts=-N -Wno-unused-packages + build-depends: + ansi-wl-pprint >=0.6.9 && <0.7, + exceptions >=0.10.4 && <0.11, + network >=3.1.2.7 && <3.2, + optparse-applicative >=0.17.0.0 && <0.18, + purescript + if flag(release) + cpp-options: -DRELEASE + else + build-depends: + gitrev >=1.2.0 && <1.4 + exposed-modules: Command.Bundle Command.Compile Command.Docs @@ -437,11 +488,14 @@ test-suite tests ghc-options: -Wno-incomplete-uni-patterns -Wno-unused-packages build-depends: purescript, + purs-lib, + flat, generic-random >=1.5.0.1 && <1.6, hspec >= 2.10.7 && < 3, HUnit >=1.6.2.0 && <1.7, newtype >=0.2.2.0 && <0.3, QuickCheck >=2.14.2 && <2.15, + plutus-core, regex-base >=0.94.0.2 && <0.95, split >=0.2.3.4 && <0.3, typed-process >=0.2.10.1 && <0.3 @@ -477,6 +531,7 @@ test-suite tests TestPsci.EvalTest TestPsci.TestEnv TestPscPublish + TestPurus TestSourceMaps TestUtils Paths_purescript diff --git a/app/Command/Bundle.hs b/purs-lib/Command/Bundle.hs similarity index 100% rename from app/Command/Bundle.hs rename to purs-lib/Command/Bundle.hs diff --git a/app/Command/Compile.hs b/purs-lib/Command/Compile.hs similarity index 83% rename from app/Command/Compile.hs rename to purs-lib/Command/Compile.hs index 8f348da9d..9cd29b37f 100644 --- a/app/Command/Compile.hs +++ b/purs-lib/Command/Compile.hs @@ -1,4 +1,4 @@ -module Command.Compile (command) where +module Command.Compile where import Prelude @@ -31,7 +31,7 @@ data PSCMakeOptions = PSCMakeOptions , pscmOpts :: P.Options , pscmUsePrefix :: Bool , pscmJSONErrors :: Bool - } + } deriving Show -- | Arguments: verbose, use JSON, warnings, errors printWarningsAndErrors :: Bool -> Bool -> [(FilePath, T.Text)] -> P.MultipleErrors -> Either P.MultipleErrors a -> IO () @@ -72,6 +72,25 @@ compile PSCMakeOptions{..} = do printWarningsAndErrors (P.optionsVerboseErrors pscmOpts) pscmJSONErrors moduleFiles makeWarnings makeErrors exitSuccess +compileForTests :: PSCMakeOptions -> IO () +compileForTests PSCMakeOptions{..} = do + included <- globWarningOnMisses warnFileTypeNotFound pscmInput + excluded <- globWarningOnMisses warnFileTypeNotFound pscmExclude + let input = included \\ excluded + if (null input) then do + hPutStr stderr $ unlines [ "purs compile: No input files." + , "Usage: For basic information, try the `--help' option." + ] + else do + moduleFiles <- readUTF8FilesT input + (makeErrors, makeWarnings) <- runMake pscmOpts $ do + ms <- CST.parseModulesFromFiles id moduleFiles + let filePathMap = M.fromList $ map (\(fp, pm) -> (P.getModuleName $ CST.resPartial pm, Right fp)) ms + foreigns <- inferForeignModules filePathMap + let makeActions = buildMakeActions pscmOutputDir filePathMap foreigns pscmUsePrefix + P.make makeActions (map snd ms) + printWarningsAndErrors (P.optionsVerboseErrors pscmOpts) pscmJSONErrors moduleFiles makeWarnings makeErrors + warnFileTypeNotFound :: String -> IO () warnFileTypeNotFound = hPutStrLn stderr . ("purs compile: No files found using pattern: " ++) @@ -130,11 +149,11 @@ codegenTargets :: Opts.Parser [P.CodegenTarget] codegenTargets = Opts.option targetParser $ Opts.short 'g' <> Opts.long "codegen" - <> Opts.value [P.JS] + <> Opts.value [P.CoreFn] <> Opts.help ( "Specifies comma-separated codegen targets to include. " <> targetsMessage - <> " The default target is 'js', but if this option is used only the targets specified will be used." + <> " The default target is 'coreFn', but if this option is used only the targets specified will be used." ) targetsMessage :: String @@ -158,7 +177,7 @@ options = where -- Ensure that the JS target is included if sourcemaps are handleTargets :: [P.CodegenTarget] -> S.Set P.CodegenTarget - handleTargets ts = S.fromList (if P.JSSourceMap `elem` ts then P.JS : ts else ts) + handleTargets ts = S.fromList ts pscMakeOptions :: Opts.Parser PSCMakeOptions pscMakeOptions = PSCMakeOptions <$> many inputFile diff --git a/app/Command/Docs.hs b/purs-lib/Command/Docs.hs similarity index 100% rename from app/Command/Docs.hs rename to purs-lib/Command/Docs.hs diff --git a/app/Command/Docs/Html.hs b/purs-lib/Command/Docs/Html.hs similarity index 100% rename from app/Command/Docs/Html.hs rename to purs-lib/Command/Docs/Html.hs diff --git a/app/Command/Docs/Markdown.hs b/purs-lib/Command/Docs/Markdown.hs similarity index 100% rename from app/Command/Docs/Markdown.hs rename to purs-lib/Command/Docs/Markdown.hs diff --git a/app/Command/Graph.hs b/purs-lib/Command/Graph.hs similarity index 100% rename from app/Command/Graph.hs rename to purs-lib/Command/Graph.hs diff --git a/app/Command/Hierarchy.hs b/purs-lib/Command/Hierarchy.hs similarity index 100% rename from app/Command/Hierarchy.hs rename to purs-lib/Command/Hierarchy.hs diff --git a/app/Command/Ide.hs b/purs-lib/Command/Ide.hs similarity index 100% rename from app/Command/Ide.hs rename to purs-lib/Command/Ide.hs diff --git a/app/Command/Publish.hs b/purs-lib/Command/Publish.hs similarity index 100% rename from app/Command/Publish.hs rename to purs-lib/Command/Publish.hs diff --git a/app/Command/REPL.hs b/purs-lib/Command/REPL.hs similarity index 100% rename from app/Command/REPL.hs rename to purs-lib/Command/REPL.hs diff --git a/app/Version.hs b/purs-lib/Version.hs similarity index 100% rename from app/Version.hs rename to purs-lib/Version.hs diff --git a/src/Language/PureScript/AST/Declarations.hs b/src/Language/PureScript/AST/Declarations.hs index e6d13c74a..4fbc7a247 100644 --- a/src/Language/PureScript/AST/Declarations.hs +++ b/src/Language/PureScript/AST/Declarations.hs @@ -13,6 +13,7 @@ import Codec.Serialise (Serialise) import Control.DeepSeq (NFData) import Data.Functor.Identity (Identity(..)) + import Data.Aeson.TH (Options(..), SumEncoding(..), defaultOptions, deriveJSON) import Data.Map qualified as M import Data.Text (Text) @@ -33,6 +34,8 @@ import Language.PureScript.TypeClassDictionaries (NamedDict) import Language.PureScript.Comments (Comment) import Language.PureScript.Environment (DataDeclType, Environment, FunctionalDependency, NameKind) import Language.PureScript.Constants.Prim qualified as C +import Language.PureScript.Constants.Purus as PLC +import Data.Aeson (ToJSON, FromJSON) -- | A map of locally-bound names in scope. type Context = [(Ident, SourceType)] @@ -155,14 +158,17 @@ addDefaultImport (Qualified toImportAs toImport) m@(Module ss coms mn decls exps isExistingImport _ = False -- | Adds import declarations to a module for an implicit Prim import and Prim --- | qualified as Prim, as necessary. +-- | qualified as Prim, as necessary. NOTE: We also add PLC builtins at this stage importPrim :: Module -> Module importPrim = let primModName = C.M_Prim + builtinModName = PLC.M_Builtin in addDefaultImport (Qualified (ByModuleName primModName) primModName) . addDefaultImport (Qualified ByNullSourcePos primModName) + . addDefaultImport (Qualified (ByModuleName builtinModName) builtinModName) + -- . addDefaultImport (Qualified ByNullSourcePos builtinModName) data NameSource = UserNamed | CompilerNamed deriving (Show, Generic, NFData, Serialise) @@ -370,7 +376,10 @@ data DataConstructorDeclaration = DataConstructorDeclaration { dataCtorAnn :: !SourceAnn , dataCtorName :: !(ProperName 'ConstructorName) , dataCtorFields :: ![(Ident, SourceType)] - } deriving (Show, Eq) + } deriving (Show, Eq, Generic) + +instance ToJSON DataConstructorDeclaration +instance FromJSON DataConstructorDeclaration mapDataCtorFields :: ([(Ident, SourceType)] -> [(Ident, SourceType)]) -> DataConstructorDeclaration -> DataConstructorDeclaration mapDataCtorFields f DataConstructorDeclaration{..} = DataConstructorDeclaration { dataCtorFields = f dataCtorFields, .. } diff --git a/src/Language/PureScript/AST/Literals.hs b/src/Language/PureScript/AST/Literals.hs index cfa2e880e..91ed3fd0f 100644 --- a/src/Language/PureScript/AST/Literals.hs +++ b/src/Language/PureScript/AST/Literals.hs @@ -6,11 +6,14 @@ module Language.PureScript.AST.Literals where import Prelude import Language.PureScript.PSString (PSString) +-- For serializing/deserializing Typed CoreFn +import GHC.Generics ( Generic ) +import Data.Aeson (FromJSON, ToJSON) -- | -- Data type for literal values. Parameterised so it can be used for Exprs and -- Binders. -- -data Literal a +data Literal a -- a ~ Expr Ann -- | -- A numeric literal -- @@ -31,8 +34,12 @@ data Literal a -- An array literal -- | ArrayLiteral [a] + -- | ArrayLiteral [Literal Void] -- | -- An object literal -- | ObjectLiteral [(PSString, a)] - deriving (Eq, Ord, Show, Functor) + deriving (Eq, Ord, Show, Functor, Generic) + +instance FromJSON a => FromJSON (Literal a) +instance ToJSON a => ToJSON (Literal a) diff --git a/src/Language/PureScript/CodeGen.hs b/src/Language/PureScript/CodeGen.hs index 02edf9ec4..a552ce52b 100644 --- a/src/Language/PureScript/CodeGen.hs +++ b/src/Language/PureScript/CodeGen.hs @@ -5,4 +5,4 @@ -- module Language.PureScript.CodeGen (module C) where -import Language.PureScript.CodeGen.JS as C +import Language.PureScript.CodeGen.UPLC as C diff --git a/src/Language/PureScript/CodeGen/JS.hs b/src/Language/PureScript/CodeGen/JS.hs deleted file mode 100644 index 14d122a37..000000000 --- a/src/Language/PureScript/CodeGen/JS.hs +++ /dev/null @@ -1,519 +0,0 @@ --- | This module generates code in the core imperative representation from --- elaborated PureScript code. -module Language.PureScript.CodeGen.JS - ( module AST - , module Common - , moduleToJs - ) where - -import Prelude -import Protolude (ordNub) - -import Control.Applicative (liftA2) -import Control.Monad (forM, replicateM, void) -import Control.Monad.Except (MonadError, throwError) -import Control.Monad.Reader (MonadReader, asks) -import Control.Monad.Supply.Class (MonadSupply, freshName) -import Control.Monad.Writer (MonadWriter, runWriterT, writer) - -import Data.Bifunctor (first) -import Data.List ((\\), intersect) -import Data.List.NonEmpty qualified as NEL (nonEmpty) -import Data.Foldable qualified as F -import Data.Map qualified as M -import Data.Set qualified as S -import Data.Maybe (fromMaybe, mapMaybe, maybeToList) -import Data.Monoid (Any(..)) -import Data.String (fromString) -import Data.Text (Text) -import Data.Text qualified as T - -import Language.PureScript.AST.SourcePos (SourceSpan, displayStartEndPos) -import Language.PureScript.CodeGen.JS.Common as Common -import Language.PureScript.CoreImp.AST (AST, InitializerEffects(..), everywhere, everywhereTopDownM, withSourceSpan) -import Language.PureScript.CoreImp.AST qualified as AST -import Language.PureScript.CoreImp.Module qualified as AST -import Language.PureScript.CoreImp.Optimizer (optimize) -import Language.PureScript.CoreFn (Ann, Bind(..), Binder(..), CaseAlternative(..), ConstructorType(..), Expr(..), Guard, Literal(..), Meta(..), Module(..), extractAnn, extractBinderAnn, modifyAnn, removeComments) -import Language.PureScript.CoreFn.Laziness (applyLazinessTransform) -import Language.PureScript.Crash (internalError) -import Language.PureScript.Errors (ErrorMessageHint(..), SimpleErrorMessage(..), - MultipleErrors(..), rethrow, errorMessage, - errorMessage', rethrowWithPosition, addHint) -import Language.PureScript.Names (Ident(..), ModuleName, ProperName(..), Qualified(..), QualifiedBy(..), runIdent, runModuleName, showIdent, showQualified) -import Language.PureScript.Options (CodegenTarget(..), Options(..)) -import Language.PureScript.PSString (PSString, mkString) -import Language.PureScript.Traversals (sndM) -import Language.PureScript.Constants.Prim qualified as C - -import System.FilePath.Posix (()) - --- | Generate code in the simplified JavaScript intermediate representation for all declarations in a --- module. -moduleToJs - :: forall m - . (MonadReader Options m, MonadSupply m, MonadError MultipleErrors m) - => Module Ann - -> Maybe PSString - -> m AST.Module -moduleToJs (Module _ coms mn _ imps exps reExps foreigns decls) foreignInclude = - rethrow (addHint (ErrorInModule mn)) $ do - let usedNames = concatMap getNames decls - let imps' = ordNub $ map snd imps - let mnLookup = renameImports usedNames imps' - (jsDecls, Any needRuntimeLazy) <- runWriterT $ mapM (moduleBindToJs mn) decls - optimized <- fmap (fmap (fmap annotatePure)) . optimize (map identToJs exps) $ if needRuntimeLazy then [runtimeLazy] : jsDecls else jsDecls - F.traverse_ (F.traverse_ checkIntegers) optimized - comments <- not <$> asks optionsNoComments - let header = if comments then coms else [] - let foreign' = maybe [] (pure . AST.Import FFINamespace) $ if null foreigns then Nothing else foreignInclude - let moduleBody = concat optimized - let (S.union (M.keysSet reExps) -> usedModuleNames, renamedModuleBody) = traverse (replaceModuleAccessors mnLookup) moduleBody - let jsImports - = map (importToJs mnLookup) - . filter (flip S.member usedModuleNames) - $ (\\ (mn : C.primModules)) imps' - let foreignExps = exps `intersect` foreigns - let standardExps = exps \\ foreignExps - let reExps' = M.toList (M.withoutKeys reExps (S.fromList C.primModules)) - let jsExports - = (maybeToList . exportsToJs foreignInclude $ foreignExps) - ++ (maybeToList . exportsToJs Nothing $ standardExps) - ++ mapMaybe reExportsToJs reExps' - return $ AST.Module header (foreign' ++ jsImports) renamedModuleBody jsExports - - where - -- Adds purity annotations to top-level values for bundlers. - -- The semantics here derive from treating top-level module evaluation as pure, which lets - -- us remove any unreferenced top-level declarations. To achieve this, we wrap any non-trivial - -- top-level values in an IIFE marked with a pure annotation. - annotatePure :: AST -> AST - annotatePure = annotateOrWrap - where - annotateOrWrap = liftA2 fromMaybe pureIife maybePure - - -- If the JS is potentially effectful (in the eyes of a bundler that - -- doesn't know about PureScript), return Nothing. Otherwise, return Just - -- the JS with any needed pure annotations added, and, in the case of a - -- variable declaration, an IIFE to be annotated. - maybePure :: AST -> Maybe AST - maybePure = maybePureGen False - - -- Like maybePure, but doesn't add a pure annotation to App. This exists - -- to prevent from doubling up on annotation comments on curried - -- applications; from experimentation, it turns out that a comment on the - -- outermost App is sufficient for the entire curried chain to be - -- considered effect-free. - maybePure' :: AST -> Maybe AST - maybePure' = maybePureGen True - - maybePureGen alreadyAnnotated = \case - AST.VariableIntroduction ss name j -> Just (AST.VariableIntroduction ss name (fmap annotateOrWrap <$> j)) - AST.App ss f args -> (if alreadyAnnotated then AST.App else pureApp) ss <$> maybePure' f <*> traverse maybePure args - AST.ArrayLiteral ss jss -> AST.ArrayLiteral ss <$> traverse maybePure jss - AST.ObjectLiteral ss props -> AST.ObjectLiteral ss <$> traverse (traverse maybePure) props - AST.Comment c js -> AST.Comment c <$> maybePure js - - js@(AST.Indexer _ _ (AST.Var _ FFINamespace)) -> Just js - - js@AST.NumericLiteral{} -> Just js - js@AST.StringLiteral{} -> Just js - js@AST.BooleanLiteral{} -> Just js - js@AST.Function{} -> Just js - js@AST.Var{} -> Just js - js@AST.ModuleAccessor{} -> Just js - - _ -> Nothing - - pureIife :: AST -> AST - pureIife val = pureApp Nothing (AST.Function Nothing Nothing [] (AST.Block Nothing [AST.Return Nothing val])) [] - - pureApp :: Maybe SourceSpan -> AST -> [AST] -> AST - pureApp ss f = AST.Comment AST.PureAnnotation . AST.App ss f - - -- Extracts all declaration names from a binding group. - getNames :: Bind Ann -> [Ident] - getNames (NonRec _ ident _) = [ident] - getNames (Rec vals) = map (snd . fst) vals - - -- Creates alternative names for each module to ensure they don't collide - -- with declaration names. - renameImports :: [Ident] -> [ModuleName] -> M.Map ModuleName Text - renameImports = go M.empty - where - go :: M.Map ModuleName Text -> [Ident] -> [ModuleName] -> M.Map ModuleName Text - go acc used (mn' : mns') = - let mnj = moduleNameToJs mn' - in if mn' /= mn && Ident mnj `elem` used - then let newName = freshModuleName 1 mnj used - in go (M.insert mn' newName acc) (Ident newName : used) mns' - else go (M.insert mn' mnj acc) used mns' - go acc _ [] = acc - - freshModuleName :: Integer -> Text -> [Ident] -> Text - freshModuleName i mn' used = - let newName = mn' <> "_" <> T.pack (show i) - in if Ident newName `elem` used - then freshModuleName (i + 1) mn' used - else newName - - -- Generates JavaScript code for a module import, binding the required module - -- to the alternative - importToJs :: M.Map ModuleName Text -> ModuleName -> AST.Import - importToJs mnLookup mn' = - let mnSafe = fromMaybe (internalError "Missing value in mnLookup") $ M.lookup mn' mnLookup - in AST.Import mnSafe (moduleImportPath mn') - - -- Generates JavaScript code for exporting at least one identifier, - -- eventually from another module. - exportsToJs :: Maybe PSString -> [Ident] -> Maybe AST.Export - exportsToJs from = fmap (flip AST.Export from) . NEL.nonEmpty . fmap runIdent - - -- Generates JavaScript code for re-exporting at least one identifier from - -- from another module. - reExportsToJs :: (ModuleName, [Ident]) -> Maybe AST.Export - reExportsToJs = uncurry exportsToJs . first (Just . moduleImportPath) - - moduleImportPath :: ModuleName -> PSString - moduleImportPath mn' = fromString (".." T.unpack (runModuleName mn') "index.js") - - -- Replaces the `ModuleAccessor`s in the AST with `Indexer`s, ensuring that - -- the generated code refers to the collision-avoiding renamed module - -- imports. Also returns set of used module names. - replaceModuleAccessors :: M.Map ModuleName Text -> AST -> (S.Set ModuleName, AST) - replaceModuleAccessors mnLookup = everywhereTopDownM $ \case - AST.ModuleAccessor _ mn' name -> - let mnSafe = fromMaybe (internalError "Missing value in mnLookup") $ M.lookup mn' mnLookup - in (S.singleton mn', accessorString name $ AST.Var Nothing mnSafe) - other -> pure other - - -- Check that all integers fall within the valid int range for JavaScript. - checkIntegers :: AST -> m () - checkIntegers = void . everywhereTopDownM go - where - go :: AST -> m AST - go (AST.Unary _ AST.Negate (AST.NumericLiteral ss (Left i))) = - -- Move the negation inside the literal; since this is a top-down - -- traversal doing this replacement will stop the next case from raising - -- the error when attempting to use -2147483648, as if left unrewritten - -- the value is `Unary Negate (NumericLiteral (Left 2147483648))`, and - -- 2147483648 is larger than the maximum allowed int. - return $ AST.NumericLiteral ss (Left (-i)) - go js@(AST.NumericLiteral ss (Left i)) = - let minInt = -2147483648 - maxInt = 2147483647 - in if i < minInt || i > maxInt - then throwError . maybe errorMessage errorMessage' ss $ IntOutOfRange i "JavaScript" minInt maxInt - else return js - go other = return other - - runtimeLazy :: AST - runtimeLazy = - AST.VariableIntroduction Nothing "$runtime_lazy" . Just . (UnknownEffects, ) . AST.Function Nothing Nothing ["name", "moduleName", "init"] . AST.Block Nothing $ - [ AST.VariableIntroduction Nothing "state" . Just . (UnknownEffects, ) . AST.NumericLiteral Nothing $ Left 0 - , AST.VariableIntroduction Nothing "val" Nothing - , AST.Return Nothing . AST.Function Nothing Nothing ["lineNumber"] . AST.Block Nothing $ - [ AST.IfElse Nothing (AST.Binary Nothing AST.EqualTo (AST.Var Nothing "state") (AST.NumericLiteral Nothing (Left 2))) (AST.Return Nothing $ AST.Var Nothing "val") Nothing - , AST.IfElse Nothing (AST.Binary Nothing AST.EqualTo (AST.Var Nothing "state") (AST.NumericLiteral Nothing (Left 1))) (AST.Throw Nothing $ AST.Unary Nothing AST.New (AST.App Nothing (AST.Var Nothing "ReferenceError") [foldl1 (AST.Binary Nothing AST.Add) - [ AST.Var Nothing "name" - , AST.StringLiteral Nothing " was needed before it finished initializing (module " - , AST.Var Nothing "moduleName" - , AST.StringLiteral Nothing ", line " - , AST.Var Nothing "lineNumber" - , AST.StringLiteral Nothing ")" - ], AST.Var Nothing "moduleName", AST.Var Nothing "lineNumber"])) Nothing - , AST.Assignment Nothing (AST.Var Nothing "state") . AST.NumericLiteral Nothing $ Left 1 - , AST.Assignment Nothing (AST.Var Nothing "val") $ AST.App Nothing (AST.Var Nothing "init") [] - , AST.Assignment Nothing (AST.Var Nothing "state") . AST.NumericLiteral Nothing $ Left 2 - , AST.Return Nothing $ AST.Var Nothing "val" - ] - ] - - -moduleBindToJs - :: forall m - . (MonadReader Options m, MonadSupply m, MonadWriter Any m, MonadError MultipleErrors m) - => ModuleName - -> Bind Ann - -> m [AST] -moduleBindToJs mn = bindToJs - where - -- Generate code in the simplified JavaScript intermediate representation for a declaration - bindToJs :: Bind Ann -> m [AST] - bindToJs (NonRec (_, _, Just IsTypeClassConstructor) _ _) = pure [] - -- Unlike other newtype constructors, type class constructors are only - -- ever applied; it's not possible to use them as values. So it's safe to - -- erase them. - bindToJs (NonRec ann ident val) = return <$> nonRecToJS ann ident val - bindToJs (Rec vals) = writer (applyLazinessTransform mn vals) >>= traverse (uncurry . uncurry $ nonRecToJS) - - -- Generate code in the simplified JavaScript intermediate representation for a single non-recursive - -- declaration. - -- - -- The main purpose of this function is to handle code generation for comments. - nonRecToJS :: Ann -> Ident -> Expr Ann -> m AST - nonRecToJS a i e@(extractAnn -> (_, com, _)) | not (null com) = do - withoutComment <- asks optionsNoComments - if withoutComment - then nonRecToJS a i (modifyAnn removeComments e) - else AST.Comment (AST.SourceComments com) <$> nonRecToJS a i (modifyAnn removeComments e) - nonRecToJS (ss, _, _) ident val = do - js <- valueToJs val - withPos ss $ AST.VariableIntroduction Nothing (identToJs ident) (Just (guessEffects val, js)) - - guessEffects :: Expr Ann -> AST.InitializerEffects - guessEffects = \case - Var _ (Qualified (BySourcePos _) _) -> NoEffects - App (_, _, Just IsSyntheticApp) _ _ -> NoEffects - _ -> UnknownEffects - - withPos :: SourceSpan -> AST -> m AST - withPos ss js = do - withSM <- asks (elem JSSourceMap . optionsCodegenTargets) - return $ if withSM - then withSourceSpan ss js - else js - - -- Generate code in the simplified JavaScript intermediate representation for a variable based on a - -- PureScript identifier. - var :: Ident -> AST - var = AST.Var Nothing . identToJs - - -- Generate code in the simplified JavaScript intermediate representation for a value or expression. - valueToJs :: Expr Ann -> m AST - valueToJs e = - let (ss, _, _) = extractAnn e in - withPos ss =<< valueToJs' e - - valueToJs' :: Expr Ann -> m AST - valueToJs' (Literal (pos, _, _) l) = - rethrowWithPosition pos $ literalToValueJS pos l - valueToJs' (Var (_, _, Just (IsConstructor _ [])) name) = - return $ accessorString "value" $ qualifiedToJS id name - valueToJs' (Var (_, _, Just (IsConstructor _ _)) name) = - return $ accessorString "create" $ qualifiedToJS id name - valueToJs' (Accessor _ prop val) = - accessorString prop <$> valueToJs val - valueToJs' (ObjectUpdate (pos, _, _) o copy ps) = do - obj <- valueToJs o - sts <- mapM (sndM valueToJs) ps - case copy of - Nothing -> extendObj obj sts - Just names -> pure $ AST.ObjectLiteral (Just pos) (map f names ++ sts) - where f name = (name, accessorString name obj) - valueToJs' (Abs _ arg val) = do - ret <- valueToJs val - let jsArg = case arg of - UnusedIdent -> [] - _ -> [identToJs arg] - return $ AST.Function Nothing Nothing jsArg (AST.Block Nothing [AST.Return Nothing ret]) - valueToJs' e@App{} = do - let (f, args) = unApp e [] - args' <- mapM valueToJs args - case f of - Var (_, _, Just IsNewtype) _ -> return (head args') - Var (_, _, Just (IsConstructor _ fields)) name | length args == length fields -> - return $ AST.Unary Nothing AST.New $ AST.App Nothing (qualifiedToJS id name) args' - _ -> flip (foldl (\fn a -> AST.App Nothing fn [a])) args' <$> valueToJs f - where - unApp :: Expr Ann -> [Expr Ann] -> (Expr Ann, [Expr Ann]) - unApp (App _ val arg) args = unApp val (arg : args) - unApp other args = (other, args) - valueToJs' (Var (_, _, Just IsForeign) qi@(Qualified (ByModuleName mn') ident)) = - return $ if mn' == mn - then foreignIdent ident - else varToJs qi - valueToJs' (Var (_, _, Just IsForeign) ident) = - internalError $ "Encountered an unqualified reference to a foreign ident " ++ T.unpack (showQualified showIdent ident) - valueToJs' (Var _ ident) = return $ varToJs ident - valueToJs' (Case (ss, _, _) values binders) = do - vals <- mapM valueToJs values - bindersToJs ss binders vals - valueToJs' (Let _ ds val) = do - ds' <- concat <$> mapM bindToJs ds - ret <- valueToJs val - return $ AST.App Nothing (AST.Function Nothing Nothing [] (AST.Block Nothing (ds' ++ [AST.Return Nothing ret]))) [] - valueToJs' (Constructor (_, _, Just IsNewtype) _ ctor _) = - return $ AST.VariableIntroduction Nothing (properToJs ctor) (Just . (UnknownEffects, ) $ - AST.ObjectLiteral Nothing [("create", - AST.Function Nothing Nothing ["value"] - (AST.Block Nothing [AST.Return Nothing $ AST.Var Nothing "value"]))]) - valueToJs' (Constructor _ _ ctor []) = - return $ iife (properToJs ctor) [ AST.Function Nothing (Just (properToJs ctor)) [] (AST.Block Nothing []) - , AST.Assignment Nothing (accessorString "value" (AST.Var Nothing (properToJs ctor))) - (AST.Unary Nothing AST.New $ AST.App Nothing (AST.Var Nothing (properToJs ctor)) []) ] - valueToJs' (Constructor _ _ ctor fields) = - let constructor = - let body = [ AST.Assignment Nothing ((accessorString $ mkString $ identToJs f) (AST.Var Nothing "this")) (var f) | f <- fields ] - in AST.Function Nothing (Just (properToJs ctor)) (identToJs `map` fields) (AST.Block Nothing body) - createFn = - let body = AST.Unary Nothing AST.New $ AST.App Nothing (AST.Var Nothing (properToJs ctor)) (var `map` fields) - in foldr (\f inner -> AST.Function Nothing Nothing [identToJs f] (AST.Block Nothing [AST.Return Nothing inner])) body fields - in return $ iife (properToJs ctor) [ constructor - , AST.Assignment Nothing (accessorString "create" (AST.Var Nothing (properToJs ctor))) createFn - ] - - iife :: Text -> [AST] -> AST - iife v exprs = AST.App Nothing (AST.Function Nothing Nothing [] (AST.Block Nothing $ exprs ++ [AST.Return Nothing $ AST.Var Nothing v])) [] - - literalToValueJS :: SourceSpan -> Literal (Expr Ann) -> m AST - literalToValueJS ss (NumericLiteral (Left i)) = return $ AST.NumericLiteral (Just ss) (Left i) - literalToValueJS ss (NumericLiteral (Right n)) = return $ AST.NumericLiteral (Just ss) (Right n) - literalToValueJS ss (StringLiteral s) = return $ AST.StringLiteral (Just ss) s - literalToValueJS ss (CharLiteral c) = return $ AST.StringLiteral (Just ss) (fromString [c]) - literalToValueJS ss (BooleanLiteral b) = return $ AST.BooleanLiteral (Just ss) b - literalToValueJS ss (ArrayLiteral xs) = AST.ArrayLiteral (Just ss) <$> mapM valueToJs xs - literalToValueJS ss (ObjectLiteral ps) = AST.ObjectLiteral (Just ss) <$> mapM (sndM valueToJs) ps - - -- Shallow copy an object. - extendObj :: AST -> [(PSString, AST)] -> m AST - extendObj obj sts = do - newObj <- freshName - key <- freshName - evaluatedObj <- freshName - let - jsKey = AST.Var Nothing key - jsNewObj = AST.Var Nothing newObj - jsEvaluatedObj = AST.Var Nothing evaluatedObj - block = AST.Block Nothing (evaluate:objAssign:copy:extend ++ [AST.Return Nothing jsNewObj]) - evaluate = AST.VariableIntroduction Nothing evaluatedObj (Just (UnknownEffects, obj)) - objAssign = AST.VariableIntroduction Nothing newObj (Just (NoEffects, AST.ObjectLiteral Nothing [])) - copy = AST.ForIn Nothing key jsEvaluatedObj $ AST.Block Nothing [AST.IfElse Nothing cond assign Nothing] - cond = AST.App Nothing (accessorString "call" (accessorString "hasOwnProperty" (AST.ObjectLiteral Nothing []))) [jsEvaluatedObj, jsKey] - assign = AST.Block Nothing [AST.Assignment Nothing (AST.Indexer Nothing jsKey jsNewObj) (AST.Indexer Nothing jsKey jsEvaluatedObj)] - stToAssign (s, js) = AST.Assignment Nothing (accessorString s jsNewObj) js - extend = map stToAssign sts - return $ AST.App Nothing (AST.Function Nothing Nothing [] block) [] - - -- Generate code in the simplified JavaScript intermediate representation for a reference to a - -- variable. - varToJs :: Qualified Ident -> AST - varToJs (Qualified (BySourcePos _) ident) = var ident - varToJs qual = qualifiedToJS id qual - - -- Generate code in the simplified JavaScript intermediate representation for a reference to a - -- variable that may have a qualified name. - qualifiedToJS :: (a -> Ident) -> Qualified a -> AST - qualifiedToJS f (Qualified (ByModuleName C.M_Prim) a) = AST.Var Nothing . runIdent $ f a - qualifiedToJS f (Qualified (ByModuleName mn') a) | mn /= mn' = AST.ModuleAccessor Nothing mn' . mkString . T.concatMap identCharToText . runIdent $ f a - qualifiedToJS f (Qualified _ a) = AST.Var Nothing $ identToJs (f a) - - foreignIdent :: Ident -> AST - foreignIdent ident = accessorString (mkString $ runIdent ident) (AST.Var Nothing FFINamespace) - - -- Generate code in the simplified JavaScript intermediate representation for pattern match binders - -- and guards. - bindersToJs :: SourceSpan -> [CaseAlternative Ann] -> [AST] -> m AST - bindersToJs ss binders vals = do - valNames <- replicateM (length vals) freshName - let assignments = zipWith (AST.VariableIntroduction Nothing) valNames (map (Just . (UnknownEffects, )) vals) - jss <- forM binders $ \(CaseAlternative bs result) -> do - ret <- guardsToJs result - go valNames ret bs - return $ AST.App Nothing (AST.Function Nothing Nothing [] (AST.Block Nothing (assignments ++ concat jss ++ [AST.Throw Nothing $ failedPatternError valNames]))) - [] - where - go :: [Text] -> [AST] -> [Binder Ann] -> m [AST] - go _ done [] = return done - go (v:vs) done' (b:bs) = do - done'' <- go vs done' bs - binderToJs v done'' b - go _ _ _ = internalError "Invalid arguments to bindersToJs" - - failedPatternError :: [Text] -> AST - failedPatternError names = AST.Unary Nothing AST.New $ AST.App Nothing (AST.Var Nothing "Error") [AST.Binary Nothing AST.Add (AST.StringLiteral Nothing $ mkString failedPatternMessage) (AST.ArrayLiteral Nothing $ zipWith valueError names vals)] - - failedPatternMessage :: Text - failedPatternMessage = "Failed pattern match at " <> runModuleName mn <> " " <> displayStartEndPos ss <> ": " - - valueError :: Text -> AST -> AST - valueError _ l@(AST.NumericLiteral _ _) = l - valueError _ l@(AST.StringLiteral _ _) = l - valueError _ l@(AST.BooleanLiteral _ _) = l - valueError s _ = accessorString "name" . accessorString "constructor" $ AST.Var Nothing s - - guardsToJs :: Either [(Guard Ann, Expr Ann)] (Expr Ann) -> m [AST] - guardsToJs (Left gs) = traverse genGuard gs where - genGuard (cond, val) = do - cond' <- valueToJs cond - val' <- valueToJs val - return - (AST.IfElse Nothing cond' - (AST.Block Nothing [AST.Return Nothing val']) Nothing) - - guardsToJs (Right v) = return . AST.Return Nothing <$> valueToJs v - - binderToJs :: Text -> [AST] -> Binder Ann -> m [AST] - binderToJs s done binder = - let (ss, _, _) = extractBinderAnn binder in - traverse (withPos ss) =<< binderToJs' s done binder - - -- Generate code in the simplified JavaScript intermediate representation for a pattern match - -- binder. - binderToJs' :: Text -> [AST] -> Binder Ann -> m [AST] - binderToJs' _ done NullBinder{} = return done - binderToJs' varName done (LiteralBinder _ l) = - literalToBinderJS varName done l - binderToJs' varName done (VarBinder _ ident) = - return (AST.VariableIntroduction Nothing (identToJs ident) (Just (NoEffects, AST.Var Nothing varName)) : done) - binderToJs' varName done (ConstructorBinder (_, _, Just IsNewtype) _ _ [b]) = - binderToJs varName done b - binderToJs' varName done (ConstructorBinder (_, _, Just (IsConstructor ctorType fields)) _ ctor bs) = do - js <- go (zip fields bs) done - return $ case ctorType of - ProductType -> js - SumType -> - [AST.IfElse Nothing (AST.InstanceOf Nothing (AST.Var Nothing varName) (qualifiedToJS (Ident . runProperName) ctor)) - (AST.Block Nothing js) - Nothing] - where - go :: [(Ident, Binder Ann)] -> [AST] -> m [AST] - go [] done' = return done' - go ((field, binder) : remain) done' = do - argVar <- freshName - done'' <- go remain done' - js <- binderToJs argVar done'' binder - return (AST.VariableIntroduction Nothing argVar (Just (UnknownEffects, accessorString (mkString $ identToJs field) $ AST.Var Nothing varName)) : js) - binderToJs' _ _ ConstructorBinder{} = - internalError "binderToJs: Invalid ConstructorBinder in binderToJs" - binderToJs' varName done (NamedBinder _ ident binder) = do - js <- binderToJs varName done binder - return (AST.VariableIntroduction Nothing (identToJs ident) (Just (NoEffects, AST.Var Nothing varName)) : js) - - literalToBinderJS :: Text -> [AST] -> Literal (Binder Ann) -> m [AST] - literalToBinderJS varName done (NumericLiteral num) = - return [AST.IfElse Nothing (AST.Binary Nothing AST.EqualTo (AST.Var Nothing varName) (AST.NumericLiteral Nothing num)) (AST.Block Nothing done) Nothing] - literalToBinderJS varName done (CharLiteral c) = - return [AST.IfElse Nothing (AST.Binary Nothing AST.EqualTo (AST.Var Nothing varName) (AST.StringLiteral Nothing (fromString [c]))) (AST.Block Nothing done) Nothing] - literalToBinderJS varName done (StringLiteral str) = - return [AST.IfElse Nothing (AST.Binary Nothing AST.EqualTo (AST.Var Nothing varName) (AST.StringLiteral Nothing str)) (AST.Block Nothing done) Nothing] - literalToBinderJS varName done (BooleanLiteral True) = - return [AST.IfElse Nothing (AST.Var Nothing varName) (AST.Block Nothing done) Nothing] - literalToBinderJS varName done (BooleanLiteral False) = - return [AST.IfElse Nothing (AST.Unary Nothing AST.Not (AST.Var Nothing varName)) (AST.Block Nothing done) Nothing] - literalToBinderJS varName done (ObjectLiteral bs) = go done bs - where - go :: [AST] -> [(PSString, Binder Ann)] -> m [AST] - go done' [] = return done' - go done' ((prop, binder):bs') = do - propVar <- freshName - done'' <- go done' bs' - js <- binderToJs propVar done'' binder - return (AST.VariableIntroduction Nothing propVar (Just (UnknownEffects, accessorString prop (AST.Var Nothing varName))) : js) - literalToBinderJS varName done (ArrayLiteral bs) = do - js <- go done 0 bs - return [AST.IfElse Nothing (AST.Binary Nothing AST.EqualTo (accessorString "length" (AST.Var Nothing varName)) (AST.NumericLiteral Nothing (Left (fromIntegral $ length bs)))) (AST.Block Nothing js) Nothing] - where - go :: [AST] -> Integer -> [Binder Ann] -> m [AST] - go done' _ [] = return done' - go done' index (binder:bs') = do - elVar <- freshName - done'' <- go done' (index + 1) bs' - js <- binderToJs elVar done'' binder - return (AST.VariableIntroduction Nothing elVar (Just (UnknownEffects, AST.Indexer Nothing (AST.NumericLiteral Nothing (Left index)) (AST.Var Nothing varName))) : js) - -accessorString :: PSString -> AST -> AST -accessorString prop = AST.Indexer Nothing (AST.StringLiteral Nothing prop) - -pattern FFINamespace :: Text -pattern FFINamespace = "$foreign" diff --git a/src/Language/PureScript/CodeGen/JS/Common.hs b/src/Language/PureScript/CodeGen/JS/Common.hs deleted file mode 100644 index e02946890..000000000 --- a/src/Language/PureScript/CodeGen/JS/Common.hs +++ /dev/null @@ -1,249 +0,0 @@ --- | Common code generation utility functions -module Language.PureScript.CodeGen.JS.Common where - -import Prelude - -import Data.Char (isAlpha, isAlphaNum, isDigit, ord) -import Data.Text (Text) -import Data.Text qualified as T - -import Language.PureScript.Crash (internalError) -import Language.PureScript.Names (Ident(..), InternalIdentData(..), ModuleName(..), ProperName(..), unusedIdent) - -moduleNameToJs :: ModuleName -> Text -moduleNameToJs (ModuleName mn) = - let name = T.replace "." "_" mn - in if nameIsJsBuiltIn name then "$$" <> name else name - --- | Convert an 'Ident' into a valid JavaScript identifier: --- --- * Alphanumeric characters are kept unmodified. --- --- * Reserved javascript identifiers and identifiers starting with digits are --- prefixed with '$$'. -identToJs :: Ident -> Text -identToJs (Ident name) - | not (T.null name) && isDigit (T.head name) = "$$" <> T.concatMap identCharToText name - | otherwise = anyNameToJs name -identToJs (GenIdent _ _) = internalError "GenIdent in identToJs" -identToJs UnusedIdent = unusedIdent -identToJs (InternalIdent RuntimeLazyFactory) = "$runtime_lazy" -identToJs (InternalIdent (Lazy name)) = "$lazy_" <> anyNameToJs name - --- | Convert a 'ProperName' into a valid JavaScript identifier: --- --- * Alphanumeric characters are kept unmodified. --- --- * Reserved javascript identifiers are prefixed with '$$'. -properToJs :: ProperName a -> Text -properToJs = anyNameToJs . runProperName - --- | Convert any name into a valid JavaScript identifier. --- --- Note that this function assumes that the argument is a valid PureScript --- identifier (either an 'Ident' or a 'ProperName') to begin with; as such it --- will not produce valid JavaScript identifiers if the argument e.g. begins --- with a digit. Prefer 'identToJs' or 'properToJs' where possible. -anyNameToJs :: Text -> Text -anyNameToJs name - | nameIsJsReserved name || nameIsJsBuiltIn name = "$$" <> name - | otherwise = T.concatMap identCharToText name - --- | Test if a string is a valid JavaScript identifier as-is. Note that, while --- a return value of 'True' guarantees that the string is a valid JS --- identifier, a return value of 'False' does not guarantee that the string is --- not a valid JS identifier. That is, this check is more conservative than --- absolutely necessary. -isValidJsIdentifier :: Text -> Bool -isValidJsIdentifier s = - not (T.null s) && - isAlpha (T.head s) && - s == anyNameToJs s - --- | Attempts to find a human-readable name for a symbol, if none has been specified returns the --- ordinal value. -identCharToText :: Char -> Text -identCharToText c | isAlphaNum c = T.singleton c -identCharToText '_' = "_" -identCharToText '.' = "$dot" -identCharToText '$' = "$dollar" -identCharToText '~' = "$tilde" -identCharToText '=' = "$eq" -identCharToText '<' = "$less" -identCharToText '>' = "$greater" -identCharToText '!' = "$bang" -identCharToText '#' = "$hash" -identCharToText '%' = "$percent" -identCharToText '^' = "$up" -identCharToText '&' = "$amp" -identCharToText '|' = "$bar" -identCharToText '*' = "$times" -identCharToText '/' = "$div" -identCharToText '+' = "$plus" -identCharToText '-' = "$minus" -identCharToText ':' = "$colon" -identCharToText '\\' = "$bslash" -identCharToText '?' = "$qmark" -identCharToText '@' = "$at" -identCharToText '\'' = "$prime" -identCharToText c = '$' `T.cons` T.pack (show (ord c)) - --- | Checks whether an identifier name is reserved in JavaScript. -nameIsJsReserved :: Text -> Bool -nameIsJsReserved name = - name `elem` jsAnyReserved - --- | Checks whether a name matches a built-in value in JavaScript. -nameIsJsBuiltIn :: Text -> Bool -nameIsJsBuiltIn name = - name `elem` - [ "arguments" - , "Array" - , "ArrayBuffer" - , "Boolean" - , "DataView" - , "Date" - , "decodeURI" - , "decodeURIComponent" - , "encodeURI" - , "encodeURIComponent" - , "Error" - , "escape" - , "eval" - , "EvalError" - , "Float32Array" - , "Float64Array" - , "Function" - , "Infinity" - , "Int16Array" - , "Int32Array" - , "Int8Array" - , "Intl" - , "isFinite" - , "isNaN" - , "JSON" - , "Map" - , "Math" - , "NaN" - , "Number" - , "Object" - , "parseFloat" - , "parseInt" - , "Promise" - , "Proxy" - , "RangeError" - , "ReferenceError" - , "Reflect" - , "RegExp" - , "Set" - , "SIMD" - , "String" - , "Symbol" - , "SyntaxError" - , "TypeError" - , "Uint16Array" - , "Uint32Array" - , "Uint8Array" - , "Uint8ClampedArray" - , "undefined" - , "unescape" - , "URIError" - , "WeakMap" - , "WeakSet" - ] - -jsAnyReserved :: [Text] -jsAnyReserved = - concat - [ jsKeywords - , jsSometimesReserved - , jsFutureReserved - , jsFutureReservedStrict - , jsOldReserved - , jsLiterals - ] - -jsKeywords :: [Text] -jsKeywords = - [ "break" - , "case" - , "catch" - , "class" - , "const" - , "continue" - , "debugger" - , "default" - , "delete" - , "do" - , "else" - , "export" - , "extends" - , "finally" - , "for" - , "function" - , "if" - , "import" - , "in" - , "instanceof" - , "new" - , "return" - , "super" - , "switch" - , "this" - , "throw" - , "try" - , "typeof" - , "var" - , "void" - , "while" - , "with" - ] - -jsSometimesReserved :: [Text] -jsSometimesReserved = - [ "await" - , "let" - , "static" - , "yield" - ] - -jsFutureReserved :: [Text] -jsFutureReserved = - [ "enum" ] - -jsFutureReservedStrict :: [Text] -jsFutureReservedStrict = - [ "implements" - , "interface" - , "package" - , "private" - , "protected" - , "public" - ] - -jsOldReserved :: [Text] -jsOldReserved = - [ "abstract" - , "boolean" - , "byte" - , "char" - , "double" - , "final" - , "float" - , "goto" - , "int" - , "long" - , "native" - , "short" - , "synchronized" - , "throws" - , "transient" - , "volatile" - ] - -jsLiterals :: [Text] -jsLiterals = - [ "null" - , "true" - , "false" - ] diff --git a/src/Language/PureScript/CodeGen/JS/Printer.hs b/src/Language/PureScript/CodeGen/JS/Printer.hs deleted file mode 100644 index 6740e2a7a..000000000 --- a/src/Language/PureScript/CodeGen/JS/Printer.hs +++ /dev/null @@ -1,310 +0,0 @@ --- | Pretty printer for the JavaScript AST -module Language.PureScript.CodeGen.JS.Printer - ( prettyPrintJS - , prettyPrintJSWithSourceMaps - ) where - -import Prelude - -import Control.Arrow ((<+>)) -import Control.Monad (forM, mzero) -import Control.Monad.State (StateT, evalStateT) -import Control.PatternArrows (Operator(..), OperatorTable(..), Pattern(..), buildPrettyPrinter, mkPattern, mkPattern') -import Control.Arrow qualified as A - -import Data.Maybe (fromMaybe) -import Data.Text (Text) -import Data.Text qualified as T -import Data.List.NonEmpty qualified as NEL (toList) - -import Language.PureScript.AST (SourceSpan(..)) -import Language.PureScript.CodeGen.JS.Common (identCharToText, isValidJsIdentifier, nameIsJsBuiltIn, nameIsJsReserved) -import Language.PureScript.CoreImp.AST (AST(..), BinaryOperator(..), CIComments(..), UnaryOperator(..), getSourceSpan) -import Language.PureScript.CoreImp.Module (Export(..), Import(..), Module(..)) -import Language.PureScript.Comments (Comment(..)) -import Language.PureScript.Crash (internalError) -import Language.PureScript.Pretty.Common (Emit(..), PrinterState(..), SMap, StrPos(..), addMapping', currentIndent, intercalate, parensPos, runPlainString, withIndent) -import Language.PureScript.PSString (PSString, decodeString, prettyPrintStringJS) - --- TODO (Christoph): Get rid of T.unpack / pack - -literals :: (Emit gen) => Pattern PrinterState AST gen -literals = mkPattern' match' - where - match' :: (Emit gen) => AST -> StateT PrinterState Maybe gen - match' js = (addMapping' (getSourceSpan js) <>) <$> match js - - match :: (Emit gen) => AST -> StateT PrinterState Maybe gen - match (NumericLiteral _ n) = return $ emit $ T.pack $ either show show n - match (StringLiteral _ s) = return $ emit $ prettyPrintStringJS s - match (BooleanLiteral _ True) = return $ emit "true" - match (BooleanLiteral _ False) = return $ emit "false" - match (ArrayLiteral _ xs) = mconcat <$> sequence - [ return $ emit "[ " - , intercalate (emit ", ") <$> forM xs prettyPrintJS' - , return $ emit " ]" - ] - match (ObjectLiteral _ []) = return $ emit "{}" - match (ObjectLiteral _ ps) = mconcat <$> sequence - [ return $ emit "{\n" - , withIndent $ do - jss <- forM ps $ \(key, value) -> fmap ((objectPropertyToString key <> emit ": ") <>) . prettyPrintJS' $ value - indentString <- currentIndent - return $ intercalate (emit ",\n") $ map (indentString <>) jss - , return $ emit "\n" - , currentIndent - , return $ emit "}" - ] - where - objectPropertyToString :: (Emit gen) => PSString -> gen - objectPropertyToString s = - emit $ case decodeString s of - Just s' | isValidJsIdentifier s' -> - s' - _ -> - prettyPrintStringJS s - match (Block _ sts) = mconcat <$> sequence - [ return $ emit "{\n" - , withIndent $ prettyStatements sts - , return $ emit "\n" - , currentIndent - , return $ emit "}" - ] - match (Var _ ident) = return $ emit ident - match (VariableIntroduction _ ident value) = mconcat <$> sequence - [ return $ emit $ "var " <> ident - , maybe (return mempty) (fmap (emit " = " <>) . prettyPrintJS' . snd) value - ] - match (Assignment _ target value) = mconcat <$> sequence - [ prettyPrintJS' target - , return $ emit " = " - , prettyPrintJS' value - ] - match (While _ cond sts) = mconcat <$> sequence - [ return $ emit "while (" - , prettyPrintJS' cond - , return $ emit ") " - , prettyPrintJS' sts - ] - match (For _ ident start end sts) = mconcat <$> sequence - [ return $ emit $ "for (var " <> ident <> " = " - , prettyPrintJS' start - , return $ emit $ "; " <> ident <> " < " - , prettyPrintJS' end - , return $ emit $ "; " <> ident <> "++) " - , prettyPrintJS' sts - ] - match (ForIn _ ident obj sts) = mconcat <$> sequence - [ return $ emit $ "for (var " <> ident <> " in " - , prettyPrintJS' obj - , return $ emit ") " - , prettyPrintJS' sts - ] - match (IfElse _ cond thens elses) = mconcat <$> sequence - [ return $ emit "if (" - , prettyPrintJS' cond - , return $ emit ") " - , prettyPrintJS' thens - , maybe (return mempty) (fmap (emit " else " <>) . prettyPrintJS') elses - ] - match (Return _ value) = mconcat <$> sequence - [ return $ emit "return " - , prettyPrintJS' value - ] - match (ReturnNoResult _) = return $ emit "return" - match (Throw _ value) = mconcat <$> sequence - [ return $ emit "throw " - , prettyPrintJS' value - ] - match (Comment (SourceComments com) js) = mconcat <$> sequence - [ return $ emit "\n" - , mconcat <$> forM com comment - , prettyPrintJS' js - ] - match (Comment PureAnnotation js) = mconcat <$> sequence - [ return $ emit "/* #__PURE__ */ " - , prettyPrintJS' js - ] - match _ = mzero - -comment :: (Emit gen) => Comment -> StateT PrinterState Maybe gen -comment (LineComment com) = mconcat <$> sequence - [ currentIndent - , return $ emit "//" <> emit com <> emit "\n" - ] -comment (BlockComment com) = fmap mconcat $ sequence $ - [ currentIndent - , return $ emit "/**\n" - ] ++ - map asLine (T.lines com) ++ - [ currentIndent - , return $ emit " */\n" - , currentIndent - ] - where - asLine :: (Emit gen) => Text -> StateT PrinterState Maybe gen - asLine s = do - i <- currentIndent - return $ i <> emit " * " <> (emit . removeComments) s <> emit "\n" - - removeComments :: Text -> Text - removeComments t = - case T.stripPrefix "*/" t of - Just rest -> removeComments rest - Nothing -> case T.uncons t of - Just (x, xs) -> x `T.cons` removeComments xs - Nothing -> "" - -prettyImport :: (Emit gen) => Import -> StateT PrinterState Maybe gen -prettyImport (Import ident from) = - return . emit $ - "import * as " <> ident <> " from " <> prettyPrintStringJS from <> ";" - -prettyExport :: (Emit gen) => Export -> StateT PrinterState Maybe gen -prettyExport (Export idents from) = - mconcat <$> sequence - [ return $ emit "export {\n" - , withIndent $ do - let exportsStrings = emit . exportedIdentToString from <$> idents - indentString <- currentIndent - return . intercalate (emit ",\n") . NEL.toList $ (indentString <>) <$> exportsStrings - , return $ emit "\n" - , currentIndent - , return . emit $ "}" <> maybe "" ((" from " <>) . prettyPrintStringJS) from <> ";" - ] - where - exportedIdentToString Nothing ident - | nameIsJsReserved ident || nameIsJsBuiltIn ident - = "$$" <> ident <> " as " <> ident - exportedIdentToString _ "$main" - = T.concatMap identCharToText "$main" <> " as $main" - exportedIdentToString _ ident - = T.concatMap identCharToText ident - -accessor :: Pattern PrinterState AST (Text, AST) -accessor = mkPattern match - where - match (Indexer _ (StringLiteral _ prop) val) = - case decodeString prop of - Just s | isValidJsIdentifier s -> Just (s, val) - _ -> Nothing - match _ = Nothing - -indexer :: (Emit gen) => Pattern PrinterState AST (gen, AST) -indexer = mkPattern' match - where - match (Indexer _ index val) = (,) <$> prettyPrintJS' index <*> pure val - match _ = mzero - -lam :: Pattern PrinterState AST ((Maybe Text, [Text], Maybe SourceSpan), AST) -lam = mkPattern match - where - match (Function ss name args ret) = Just ((name, args, ss), ret) - match _ = Nothing - -app :: (Emit gen) => Pattern PrinterState AST (gen, AST) -app = mkPattern' match - where - match (App _ val args) = do - jss <- traverse prettyPrintJS' args - return (intercalate (emit ", ") jss, val) - match _ = mzero - -instanceOf :: Pattern PrinterState AST (AST, AST) -instanceOf = mkPattern match - where - match (InstanceOf _ val ty) = Just (val, ty) - match _ = Nothing - -unary' :: (Emit gen) => UnaryOperator -> (AST -> Text) -> Operator PrinterState AST gen -unary' op mkStr = Wrap match (<>) - where - match :: (Emit gen) => Pattern PrinterState AST (gen, AST) - match = mkPattern match' - where - match' (Unary _ op' val) | op' == op = Just (emit $ mkStr val, val) - match' _ = Nothing - -unary :: (Emit gen) => UnaryOperator -> Text -> Operator PrinterState AST gen -unary op str = unary' op (const str) - -negateOperator :: (Emit gen) => Operator PrinterState AST gen -negateOperator = unary' Negate (\v -> if isNegate v then "- " else "-") - where - isNegate (Unary _ Negate _) = True - isNegate _ = False - -binary :: (Emit gen) => BinaryOperator -> Text -> Operator PrinterState AST gen -binary op str = AssocL match (\v1 v2 -> v1 <> emit (" " <> str <> " ") <> v2) - where - match :: Pattern PrinterState AST (AST, AST) - match = mkPattern match' - where - match' (Binary _ op' v1 v2) | op' == op = Just (v1, v2) - match' _ = Nothing - -prettyStatements :: (Emit gen) => [AST] -> StateT PrinterState Maybe gen -prettyStatements sts = do - jss <- forM sts prettyPrintJS' - indentString <- currentIndent - return $ intercalate (emit "\n") $ map ((<> emit ";") . (indentString <>)) jss - -prettyModule :: (Emit gen) => Module -> StateT PrinterState Maybe gen -prettyModule Module{..} = do - header <- mconcat <$> traverse comment modHeader - imps <- traverse prettyImport modImports - body <- prettyStatements modBody - exps <- traverse prettyExport modExports - pure $ header <> intercalate (emit "\n") (imps ++ body : exps) - --- | Generate a pretty-printed string representing a collection of JavaScript expressions at the same indentation level -prettyPrintJSWithSourceMaps :: Module -> (Text, [SMap]) -prettyPrintJSWithSourceMaps js = - let StrPos (_, s, mp) = (fromMaybe (internalError "Incomplete pattern") . flip evalStateT (PrinterState 0) . prettyModule) js - in (s, mp) - -prettyPrintJS :: Module -> Text -prettyPrintJS = maybe (internalError "Incomplete pattern") runPlainString . flip evalStateT (PrinterState 0) . prettyModule - --- | Generate an indented, pretty-printed string representing a JavaScript expression -prettyPrintJS' :: (Emit gen) => AST -> StateT PrinterState Maybe gen -prettyPrintJS' = A.runKleisli $ runPattern matchValue - where - matchValue :: (Emit gen) => Pattern PrinterState AST gen - matchValue = buildPrettyPrinter operators (literals <+> fmap parensPos matchValue) - operators :: (Emit gen) => OperatorTable PrinterState AST gen - operators = - OperatorTable [ [ Wrap indexer $ \index val -> val <> emit "[" <> index <> emit "]" ] - , [ Wrap accessor $ \prop val -> val <> emit "." <> emit prop ] - , [ Wrap app $ \args val -> val <> emit "(" <> args <> emit ")" ] - , [ unary New "new " ] - , [ Wrap lam $ \(name, args, ss) ret -> addMapping' ss <> - emit ("function " - <> fromMaybe "" name - <> "(" <> intercalate ", " args <> ") ") - <> ret ] - , [ unary Not "!" - , unary BitwiseNot "~" - , unary Positive "+" - , negateOperator ] - , [ binary Multiply "*" - , binary Divide "/" - , binary Modulus "%" ] - , [ binary Add "+" - , binary Subtract "-" ] - , [ binary ShiftLeft "<<" - , binary ShiftRight ">>" - , binary ZeroFillShiftRight ">>>" ] - , [ binary LessThan "<" - , binary LessThanOrEqualTo "<=" - , binary GreaterThan ">" - , binary GreaterThanOrEqualTo ">=" - , AssocR instanceOf $ \v1 v2 -> v1 <> emit " instanceof " <> v2 ] - , [ binary EqualTo "===" - , binary NotEqualTo "!==" ] - , [ binary BitwiseAnd "&" ] - , [ binary BitwiseXor "^" ] - , [ binary BitwiseOr "|" ] - , [ binary And "&&" ] - , [ binary Or "||" ] - ] diff --git a/src/Language/PureScript/CodeGen/UPLC.hs b/src/Language/PureScript/CodeGen/UPLC.hs new file mode 100644 index 000000000..5c7a8ed29 --- /dev/null +++ b/src/Language/PureScript/CodeGen/UPLC.hs @@ -0,0 +1,154 @@ +{-# OPTIONS_GHC -Wno-redundant-constraints #-} +{-# LANGUAGE TypeApplications #-} +module Language.PureScript.CodeGen.UPLC where + +import Prelude ((.), ($)) +import Protolude + ( ($), + Monad, + Maybe, + (.), + MonadError, + MonadIO(..), + print, + undefined, + MonadReader, + MonadState, (<$>) ) +import Protolude.Error (error) + +import Control.Monad.Except (MonadError) +import Control.Monad.Reader (MonadReader) +import Control.Monad.Supply.Class (MonadSupply) +import Control.Monad.IO.Class (MonadIO (liftIO)) + +import Language.PureScript.AST qualified as AST +import Language.PureScript.CoreFn (Ann, Module(..), Expr(..), Literal(..), Meta, Bind) +import Language.PureScript.Errors (MultipleErrors(..)) +import Language.PureScript.Options (Options(..)) + +import PlutusCore.Pretty ( prettyPlcReadableDef ) +import PlutusCore (someValue) +import Data.String (IsString(fromString)) +import Language.PureScript.Names (Ident(..)) +import Language.PureScript.Types qualified as T +import Language.PureScript.TypeChecker.Types (infer) +import PlutusCore qualified as PLC +import PlutusIR qualified as PIR +import Language.PureScript.TypeChecker (CheckState) +import Control.Monad.Writer.Class (MonadWriter) +import Language.PureScript.Comments (Comment) +import Language.PureScript.Types (SourceType) + +-- Stolen from Ply, not 100% sure if this is what we want, i.e. maybe there should be an annotation? +type PIRProgram = PIR.Program PLC.TyName PLC.DeBruijn PLC.DefaultUni PLC.DefaultFun () + +type PIRTerm ann = PIR.Term PLC.TyName PLC.Name PLC.DefaultUni PLC.DefaultFun ann + +sourceSpan :: Ann -> AST.SourceSpan +sourceSpan (x,_,_) = x + +comments :: Ann -> [Comment] +comments (_,x,_) = x + +meta :: Ann -> Maybe Meta +meta (_,_,x) = x + +moduleToUPLC :: forall m + . (MonadReader Options m, MonadSupply m, MonadError MultipleErrors m) + => Module (Bind Ann) Ann -> m PIRProgram +moduleToUPLC = error "Error: UPLC Backend not yet implemented!" + + + +type M m = (Monad m, MonadSupply m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) +{- +transformExpr :: forall m b + . M m + => Expr Ann + -> m (Expr (SourceType,Ann)) +transformExpr = \case + Literal ann cfnLit -> case cfnLit of + NumericLiteral x -> do + TypedValue' <- infer $ AST.Literal (sourceSpan ann) $ NumericLiteral x + pure $ Literal + StringLiteral psString -> f ann $ AST.Literal (sourceSpan ann) $ StringLiteral psString + CharLiteral c -> f ann $ AST.Literal (sourceSpan ann) $ CharLiteral c + BooleanLiteral b -> f ann $ AST.Literal (sourceSpan ann) $ BooleanLiteral b + ArrayLiteral xs -> Literal $ ArrayLiteral $ foldExpr f <$> xs + + Constructor ann tyName ctorName fields -> undefined + Accessor ann l t -> undefined + ObjectUpdate a orig copyFields updateFields -> undefined + Abs ann identifier body -> undefined + App ann e1 e2 -> undefined + Var ann qualIdent -> undefined + Case ann es alts -> undefined + Let ann binds expr -> undefined +-} + +inferExprTypes :: forall m a + . (MonadSupply m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) + => Expr a + -> m (Expr (T.Type a)) +inferExprTypes = \case + _ -> undefined + +{-| nil = constr 0 [] + cons x xs = constr 1 x xs + +sopList :: forall name ann. ann -> [PIRTerm ann] -> PIRTerm ann +sopList ann = \case -- ann is the default annotation for an empty list + [] -> PIR.Constr ann 0 [] + (x:xs) -> PIR.Constr ann 1 [x,sopList ann xs] + + + +exprToTerm :: forall m ann + . (MonadReader Options m, + MonadSupply m, + MonadError MultipleErrors m, + Monoid ann + ) => Expr ann -> m (PIRTerm ann) +exprToTerm = \case + Literal ann lit -> litToTerm ann lit + Constructor ann tyName ctorName identifiers -> undefined + Accessor ann label expr -> undefined + ObjectUpdate ann expr copyFields updateFields -> undefined + Abs ann identifier expr -> do + name <- identifierToName identifier + body <- exprToTerm expr + pure $PIR.LamAbs ann name body + App ann e1 e2 -> undefined + Var ann qIdentifier -> undefined + Case ann es cas -> undefined + Let ann binds expr -> undefined + where + identifierToName :: Ident -> m PIR.Name + identifierToName = \case + GenIdent (Just nm) i -> pure $ PIR.Name nm (PLC.Unique $ fromIntegral i) + _ -> error "WIP" + + litToTerm :: ann -> Literal (Expr ann) -> m (PIRTerm ann) + litToTerm a = \case + NumericLiteral (Left integer) -> pure $ PIR.Constant a (someValue integer) + NumericLiteral (Right _double) -> error "Figure out what to do w/ Doubles" + StringLiteral psString -> do + let bs :: ByteString = fromString (show psString) + pure $ PIR.Constant a (someValue bs) + CharLiteral _char -> error "Figure out what to do with Chars" + BooleanLiteral boolean -> pure $ PIR.Constant a (someValue boolean) + ArrayLiteral array -> sopList mempty <$> traverse exprToTerm array + {- ObjectLiterals, aka Record literals, get represented onchain as products with field order determined by lexicographic sorting of the labels. + -} + ObjectLiteral fields -> do + let sorted = map snd . sortOn fst $ fields -- these are probably already sorted somewhere, but not 100% sure + terms <- traverse exprToTerm sorted + pure $ PIR.Constr a 0 terms -- the evaluator should use 0 based indices? i hope? + +-} + + + + +printUPLC :: forall m. MonadIO m => PIRProgram -> m () +printUPLC program = liftIO . print $ prettyPlcReadableDef program diff --git a/src/Language/PureScript/Constants/PLC.hs b/src/Language/PureScript/Constants/PLC.hs new file mode 100644 index 000000000..556ef0cc8 --- /dev/null +++ b/src/Language/PureScript/Constants/PLC.hs @@ -0,0 +1,8 @@ +{-# LANGUAGE TemplateHaskell, QuasiQuotes, TemplateHaskellQuotes #-} +module Language.PureScript.Constants.PLC where + +import Language.PureScript.Constants.Purus +import PlutusCore.Default +import Language.PureScript.Constants.PLC.TH + +mkBuiltinMap ''DefaultFun diff --git a/src/Language/PureScript/Constants/PLC/TH.hs b/src/Language/PureScript/Constants/PLC/TH.hs new file mode 100644 index 000000000..f23970d3b --- /dev/null +++ b/src/Language/PureScript/Constants/PLC/TH.hs @@ -0,0 +1,67 @@ +{-# LANGUAGE TemplateHaskell, QuasiQuotes, TemplateHaskellQuotes #-} +module Language.PureScript.Constants.PLC.TH where + +import Prelude + +import Language.Haskell.TH + ( mkName, + Exp(ListE, TupE, LitE, ConE, AppE), + Clause(Clause), + Q, + Dec(FunD), + Name, + Lit(StringL), + nameBase, + Body(NormalB) ) +import Language.Haskell.TH.Datatype + ( ConstructorInfo(ConstructorInfo, constructorName), + DatatypeInfo(DatatypeInfo, datatypeContext, datatypeCons, + datatypeVariant, datatypeInstTypes, datatypeVars, datatypeName), + reifyDatatype, + ConstructorVariant(NormalConstructor) ) +import Data.Functor ((<&>)) +import Data.Map qualified as M +import Data.Char (toLower) + +isNormalNullaryCtor :: ConstructorInfo -> Bool +isNormalNullaryCtor (ConstructorInfo _ [] [] [] [] NormalConstructor) = True +isNormalNullaryCtor _ = False + +lowerName :: Name -> String +lowerName nm = case nameBase nm of + (x:xs) -> toLower x:xs + other -> other + +ctorBaseNames :: Name -> Q [String] +ctorBaseNames nm = do + DatatypeInfo{..} <- reifyDatatype nm + pure $ lowerName . constructorName <$> datatypeCons + +{- This takes the name of a Sum type w/ only Nullary constructors (t) and + creates a `Map String t` from the name (w/ a lowercase'd first char to make PS + TH machinery happy) to the corresponding constructor. + + We need this to convert to PIR. Builtin functions are free variables, and + the only information we can embed in a Var is the qualified name. During + conversion to PIR, we have to be able to lookup the Builtin that correspond to + the string in the Var. +-} +mkBuiltinMap :: Name -> Q [Dec] +mkBuiltinMap nm = do + DatatypeInfo{..} <- reifyDatatype nm + let ctors = datatypeCons + if all isNormalNullaryCtor ctors + then do + let ctorNames = constructorName <$> ctors + baseAndQualified = ctorNames <&> \x -> + TupE + [Just . LitE . StringL . lowerName $ x, + Just (ConE x)] + fromListE <- [e| M.fromList |] + let body = AppE fromListE (ListE baseAndQualified) + + pure [FunD (mkName $ lowerName nm <> "Map") [Clause [] (NormalB body) [] ]] + else fail + $ "Cannot construct a Map for type " + <> show nm + <> " because at least one ctor is not a normal, nullary ctor" diff --git a/src/Language/PureScript/Constants/Purus.hs b/src/Language/PureScript/Constants/Purus.hs new file mode 100644 index 000000000..62bd04f1a --- /dev/null +++ b/src/Language/PureScript/Constants/Purus.hs @@ -0,0 +1,30 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE TemplateHaskell #-} + +module Language.PureScript.Constants.Purus where + +import Prelude +import Language.PureScript.Constants.TH qualified as TH +import PlutusCore.Default ( DefaultFun ) +import Language.PureScript.Constants.PLC.TH +import Data.Foldable (traverse_) + +$(ctorBaseNames ''DefaultFun >>= \builtins -> TH.declare $ do + TH.mod "Builtin" do + -- We can't really TH in the primitive types of DefaultUni + -- (and anyway some of those types don't need representation + -- here, b/c they correspond to Prim types), so we define them + -- here. + -- NOTE: Integer/ByteString/Text/Unit/Bool correspond to their Prim types, this is everything else + TH.ty "BuiltinData" -- Opaque Plutus Data *Kind* (nullary) + TH.ty "BuiltinPair" + TH.ty "BuiltinList" + TH.ty "BuiltinByteString" + TH.ty "BuiltinUnit" + + -- We'll need this sooner or later + TH.ty "AsData" + + -- Generates primitives from all the builtins + TH.asIdent $ traverse_ TH.var builtins + ) diff --git a/src/Language/PureScript/CoreFn/Ann.hs b/src/Language/PureScript/CoreFn/Ann.hs index 185f8beb5..cd26983a6 100644 --- a/src/Language/PureScript/CoreFn/Ann.hs +++ b/src/Language/PureScript/CoreFn/Ann.hs @@ -17,6 +17,9 @@ type Ann = (SourceSpan, [Comment], Maybe Meta) ssAnn :: SourceSpan -> Ann ssAnn ss = (ss, [], Nothing) +annSS :: Ann -> SourceSpan +annSS (ss,_,_) = ss + -- | -- Remove the comments from an annotation -- diff --git a/src/Language/PureScript/CoreFn/Binders.hs b/src/Language/PureScript/CoreFn/Binders.hs index 4b64b97c4..62d1fcf71 100644 --- a/src/Language/PureScript/CoreFn/Binders.hs +++ b/src/Language/PureScript/CoreFn/Binders.hs @@ -8,6 +8,9 @@ import Prelude import Language.PureScript.AST.Literals (Literal) import Language.PureScript.Names (Ident, ProperName, ProperNameType(..), Qualified) +import GHC.Generics +import Data.Aeson (FromJSON, ToJSON) + -- | -- Data type for binders -- @@ -31,8 +34,10 @@ data Binder a -- | -- A binder which binds its input to an identifier -- - | NamedBinder a Ident (Binder a) deriving (Eq, Ord, Show, Functor) + | NamedBinder a Ident (Binder a) deriving (Eq, Ord, Show, Functor, Generic) +instance FromJSON a => FromJSON (Binder a) +instance ToJSON a => ToJSON (Binder a) extractBinderAnn :: Binder a -> a extractBinderAnn (NullBinder a) = a diff --git a/src/Language/PureScript/CoreFn/CSE.hs b/src/Language/PureScript/CoreFn/CSE.hs index 576243c25..4c683409c 100644 --- a/src/Language/PureScript/CoreFn/CSE.hs +++ b/src/Language/PureScript/CoreFn/CSE.hs @@ -23,6 +23,7 @@ import Language.PureScript.Constants.Libs qualified as C import Language.PureScript.CoreFn.Ann (Ann) import Language.PureScript.CoreFn.Binders (Binder(..)) import Language.PureScript.CoreFn.Expr (Bind(..), CaseAlternative(..), Expr(..)) +import Language.PureScript.CoreFn.Utils (exprType) import Language.PureScript.CoreFn.Meta (Meta(IsSyntheticApp)) import Language.PureScript.CoreFn.Traversals (everywhereOnValues, traverseCoreFn) import Language.PureScript.Environment (dictTypeName) @@ -246,18 +247,18 @@ generateIdentFor d e = at d . non mempty . at e %%<~ \case -- enables doing monadic work in the RHS, namely `freshIdent` here.) where nameHint = \case - App _ v1 v2 - | Var _ n <- v1 + App _ v1 v2 + | Var _ _ n <- v1 , fmap (ProperName . runIdent) n == fmap dictTypeName C.IsSymbol - , Literal _ (ObjectLiteral [(_, Abs _ _ (Literal _ (StringLiteral str)))]) <- v2 + , Literal _ _ (ObjectLiteral [(_, Abs _ _ _ (Literal _ _ (StringLiteral str)))]) <- v2 , Just decodedStr <- decodeString str -> decodedStr <> "IsSymbol" | otherwise -> nameHint v1 - Var _ (Qualified _ ident) + Var _ _ (Qualified _ ident) | Ident name <- ident -> name | GenIdent (Just name) _ <- ident -> name - Accessor _ prop _ + Accessor _ _ prop _ | Just decodedProp <- decodeString prop -> decodedProp _ -> "ref" @@ -270,7 +271,7 @@ nullAnn = (nullSourceSpan, [], Nothing) replaceLocals :: M.Map Ident (Expr Ann) -> [Bind Ann] -> [Bind Ann] replaceLocals m = if M.null m then identity else map f' where (f', g', _) = everywhereOnValues identity f identity - f e@(Var _ (Qualified _ ident)) = maybe e g' $ ident `M.lookup` m + f e@(Var _ _ (Qualified _ ident)) = maybe e g' $ ident `M.lookup` m f e = e -- | @@ -292,7 +293,7 @@ floatExpr topLevelQB = \case let w' = w & (if isNew then newBindings %~ addToScope deepestScope [(ident, (_plurality, e))] else identity) & plurality .~ PluralityMap (M.singleton ident False) - pure (Var nullAnn (Qualified qb ident), w') + pure (Var nullAnn (exprType e) (Qualified qb ident), w') (e, w) -> pure (e, w) -- | @@ -386,13 +387,13 @@ optimizeCommonSubexpressions mn -- common subexpression elimination pass. shouldFloatExpr :: Expr Ann -> Bool shouldFloatExpr = \case - App (_, _, Just IsSyntheticApp) e _ -> isSimple e + App (_, _, Just IsSyntheticApp) e _ -> isSimple e _ -> False isSimple :: Expr Ann -> Bool isSimple = \case Var{} -> True - Accessor _ _ e -> isSimple e + Accessor _ _ _ e -> isSimple e _ -> False handleAndWrapExpr :: Expr Ann -> CSEMonad (Expr Ann) @@ -404,8 +405,8 @@ optimizeCommonSubexpressions mn handleExpr :: Expr Ann -> CSEMonad (Expr Ann) handleExpr = discuss (ifM (shouldFloatExpr . fst) (floatExpr topLevelQB) pure) . \case - Abs a ident e -> enterAbs $ Abs a ident <$> newScopeWithIdents False [ident] (handleAndWrapExpr e) - v@(Var _ qname) -> summarizeName mn qname $> v + Abs a t ident e -> enterAbs $ Abs a t ident <$> newScopeWithIdents False [ident] (handleAndWrapExpr e) + v@(Var _ _ qname) -> summarizeName mn qname $> v Let a bs e -> uncurry (Let a) <$> handleBinds False (handleExpr e) bs x -> handleExprDefault x diff --git a/src/Language/PureScript/CoreFn/Convert.hs b/src/Language/PureScript/CoreFn/Convert.hs new file mode 100644 index 000000000..2ea9ba36f --- /dev/null +++ b/src/Language/PureScript/CoreFn/Convert.hs @@ -0,0 +1,5 @@ +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} + +module Language.PureScript.CoreFn.Convert where diff --git a/src/Language/PureScript/CoreFn/Convert/DesugarCore.hs b/src/Language/PureScript/CoreFn/Convert/DesugarCore.hs new file mode 100644 index 000000000..3a5cc4673 --- /dev/null +++ b/src/Language/PureScript/CoreFn/Convert/DesugarCore.hs @@ -0,0 +1,193 @@ +{-# OPTIONS_GHC -Werror -Wno-orphans #-} +{-# LANGUAGE TypeApplications #-} +module Language.PureScript.CoreFn.Convert.DesugarCore (WithObjects, desugarCore, desugarCoreModule) where + +import Prelude + +import Language.PureScript.Types (Type(..)) +import Language.PureScript.Names (Ident, Qualified(Qualified), + QualifiedBy (ByModuleName, BySourcePos), + pattern ByNullSourcePos, + ModuleName (ModuleName), ProperName (ProperName), disqualify) +import Language.PureScript.CoreFn.Expr (Expr(..), PurusType, Bind (NonRec, Rec), + CaseAlternative(CaseAlternative), _Var) +import Language.PureScript.CoreFn.Ann (Ann, annSS) +import Language.PureScript.CoreFn.Convert.IR hiding ((:~>)) +import Data.Map qualified as M +import Language.PureScript.AST.Literals (Literal (..)) +import Bound (abstract) +import Control.Monad (join) +import Data.List (find) +import Language.PureScript.CoreFn.Utils (exprType, Context) +import Language.PureScript.CoreFn (Binder (..)) +import Data.Maybe (mapMaybe) +import Control.Lens.Operators ((^..)) +import Control.Lens.IndexedPlated (icosmos) +import Control.Lens.Combinators (to) +import Control.Monad.Error.Class (MonadError(throwError)) +import Language.PureScript.AST.SourcePos (spanStart) +import Language.PureScript.CoreFn.Module (Module(..)) +import Language.PureScript.CoreFn.Pretty (renderExprStr) +import Debug.Trace (traceM) +import Language.PureScript.CoreFn.Desugar.Utils (wrapTrace, showIdent') + +-- TODO: Something more reasonable +type DS = Either String + +data WithObjects + +type instance XAccessor WithObjects = () +type instance XObjectUpdate WithObjects = () +type instance XObjectLiteral WithObjects = () + +type IR_Decl = BindE PurusType (Exp WithObjects PurusType) (FVar PurusType) + +desugarCoreModule :: Module (Bind Ann) Ann -> DS (Module IR_Decl Ann) +desugarCoreModule Module{..} = do + decls <- traverse desugarCoreDecl moduleDecls + pure $ Module {moduleDecls = decls,..} + +desugarCoreDecl :: Bind Ann + -> Either String (BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)) +desugarCoreDecl = \case + NonRec _ ident expr -> wrapTrace ("desugarCoreDecl: " <> showIdent' ident) $ + NonRecursive ident <$> desugarCore' expr + Rec xs -> Recursive + <$> traverse (\((_,ident),expr) -> + wrapTrace ("desugarCoreDecl: " <> showIdent' ident) $ + (ident,) + <$> desugarCore' expr) xs + +desugarCore' :: Expr Ann -> DS (Exp WithObjects PurusType (FVar PurusType)) +desugarCore' e = do + traceM $ "desugarCore INPUT: " <> renderExprStr e + res <- desugarCore e + traceM $ "desugarCore OUTPUT: " <> ppExp res + pure res + + +desugarCore :: Expr Ann -> DS (Exp WithObjects PurusType (FVar PurusType)) +desugarCore (Literal _ann ty lit) = LitE ty <$> desugarLit lit +desugarCore (Constructor _ann ty tn cn fs) = pure $ CtorE ty tn cn fs +desugarCore (Abs _ann ty ident expr) = do + expr' <- desugarCore expr + let !ty' = functionArgumentIfFunction ty + let scopedExpr = abstract (matchVarLamAbs ty' ident) expr' + pure $ LamE ty (BVar 0 ty' ident) scopedExpr +desugarCore (App _ann expr1 expr2) = do + expr1' <- desugarCore expr1 + expr2' <- desugarCore expr2 + pure $ AppE expr1' expr2' +desugarCore (Var _ann ty qi) = pure $ V $ FVar ty qi +desugarCore (Let _ann binds cont) = do + binds' <- desugarBinds binds + cont' <- desugarCore cont + let allBoundIdents = fst <$> join binds' + abstr = abstract $ abstractMany allBoundIdents + bindEs = assembleBindEs [] binds' + bindings = mkBindings allBoundIdents + pure $ LetE bindings bindEs $ abstr cont' +desugarCore (Accessor _ann ty label expr) = do + expr' <- desugarCore expr + pure $ AccessorE () ty label expr' +desugarCore (ObjectUpdate _ann ty expr toCopy toUpdate) = do + expr' <- desugarCore expr + toUpdate' <- desugarObjectMembers toUpdate + pure $ ObjectUpdateE () ty expr' toCopy toUpdate' +desugarCore (Case _ann ty scrutinees alts) = do + scrutinees' <- traverse desugarCore scrutinees + alts' <- traverse desugarAlt alts + pure $ CaseE ty scrutinees' alts' + +desugarAlt :: CaseAlternative Ann -> DS (Alt WithObjects PurusType (Exp WithObjects PurusType) (FVar PurusType)) +desugarAlt (CaseAlternative binders result) = do + let boundVars = concatMap (getBoundVar result) binders + let pats = map toPat binders + abstrE = abstract (abstractMany boundVars) + case result of + Left exs -> do + throwError $ "internal error: guarded alt not expected at this stage: " <> show exs + Right ex -> do + re <- desugarCore ex + pure $ UnguardedAlt (mkBindings boundVars) pats (abstrE re) + +getBoundVar :: Either [(Expr ann, Expr ann)] (Expr ann) -> Binder ann -> [FVar PurusType] +getBoundVar body binder = case binder of + ConstructorBinder _ _ _ binders -> concatMap (getBoundVar body) binders + LiteralBinder _ (ArrayLiteral arrBinders) -> concatMap (getBoundVar body) arrBinders + LiteralBinder _ (ObjectLiteral objBinders) -> concatMap (getBoundVar body . snd) objBinders + VarBinder _ ident -> case body of + Right expr -> case findBoundVar ident expr of + Nothing -> [] -- probably should trace or warn at least + Just (ty, qi) -> [FVar ty qi] + Left fml -> do + let allResults = concatMap (\(x,y) -> [x,y]) fml + matchingVar = mapMaybe (findBoundVar ident) allResults + case matchingVar of + ((ty, qi) : _) -> [FVar ty qi] + _ -> [] + _ -> [] + +findBoundVar :: Ident -> Expr ann -> Maybe (PurusType, Qualified Ident) +findBoundVar nm ex = find (goFind . snd) (allVars ex) + where + goFind = \case + Qualified (ByModuleName _) _ -> False + Qualified ByNullSourcePos _ -> False -- idk about this actually, guess we'll find out + Qualified (BySourcePos _) nm' -> nm == nm' + +allVars :: forall ann. Expr ann -> [(PurusType, Qualified Ident)] +allVars ex = ex ^.. icosmos @Context @(Expr ann) M.empty . _Var . to (\(_,b,c) -> (b,c)) + +qualifySS :: Ann -> Ident -> Qualified Ident +qualifySS ann i = Qualified (BySourcePos $ spanStart (annSS ann)) i + +-- Stolen from DesugarObjects +desugarBinds :: [Bind Ann] -> DS [[(FVar PurusType, Exp WithObjects PurusType (FVar PurusType))]] +desugarBinds [] = pure [] +desugarBinds (b:bs) = case b of + NonRec _ann ident expr -> do + let qualifiedIdent = qualifySS _ann ident + e' <- desugarCore expr + rest <- desugarBinds bs + pure $ [(FVar (exprType expr) qualifiedIdent,e')] : rest + -- TODO: Fix this to preserve recursivity (requires modifying the *LET* ctor of Exp) + Rec xs -> do + let xs' = map (\((ann,nm),e) -> NonRec ann nm e) xs + xs'' <- desugarBinds xs' + rest <- desugarBinds bs + pure $ xs'' <> rest + +desugarLit :: Literal (Expr Ann) -> DS (Lit WithObjects (Exp WithObjects PurusType (FVar PurusType))) +desugarLit (NumericLiteral (Left int)) = pure $ IntL int +desugarLit (NumericLiteral (Right number)) = pure $ NumL number +desugarLit (StringLiteral string) = pure $ StringL string +desugarLit (CharLiteral char) = pure $ CharL char +desugarLit (BooleanLiteral bool) = pure $ BoolL bool +desugarLit (ArrayLiteral arr) = ArrayL <$> traverse desugarCore arr +desugarLit (ObjectLiteral object) = ObjectL () <$> desugarObjectMembers object + +-- this looks like existing monadic combinator but I couldn't find it +desugarObjectMembers :: [(field, Expr Ann)] -> DS [(field, Exp WithObjects PurusType (FVar PurusType))] +desugarObjectMembers = traverse (\(memberName, val) -> (memberName,) <$> desugarCore val) + +pattern (:~>) :: PurusType -> PurusType -> PurusType +pattern a :~> b <- + (TypeApp _ + (TypeApp _ + (TypeConstructor _ (Qualified (ByModuleName (ModuleName "Prim")) (ProperName "Function"))) a) b) +infixr 0 :~> + +functionArgumentIfFunction :: PurusType -> PurusType +functionArgumentIfFunction (arg :~> _) = arg +functionArgumentIfFunction t = t + +-- | For usage with `Bound`, use only with lambda +matchVarLamAbs :: Eq ty => ty -> Ident -> FVar ty -> Maybe (BVar ty) +matchVarLamAbs t nm (FVar ty n') + | ty == t && nm == disqualify n' = Just (BVar 0 t nm) + | otherwise = Nothing + +-- TODO (t4ccer): Move somehwere, but cycilc imports are annoying +instance FuncType PurusType where + headArg = functionArgumentIfFunction diff --git a/src/Language/PureScript/CoreFn/Convert/DesugarObjects.hs b/src/Language/PureScript/CoreFn/Convert/DesugarObjects.hs new file mode 100644 index 000000000..74e0a451e --- /dev/null +++ b/src/Language/PureScript/CoreFn/Convert/DesugarObjects.hs @@ -0,0 +1,494 @@ +{-# OPTIONS_GHC -Wno-orphans #-} -- has to be here (more or less) +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} + +module Language.PureScript.CoreFn.Convert.DesugarObjects where + +{- turning this module off for now to test the monomorphizer rewrite +import Prelude +import Language.PureScript.CoreFn.Expr + ( _Var, + Bind(..), + CaseAlternative(CaseAlternative), + Expr(..) ) +import Language.PureScript.Names (Ident(..), Qualified (..), QualifiedBy (..), pattern ByNullSourcePos, ProperNameType (..), ProperName(..), disqualify, ModuleName (..), runModuleName) +import Language.PureScript.Types + ( SourceType, Type(..), srcTypeConstructor, srcTypeApp, RowListItem (rowListType), rowToList, eqType ) +import Language.PureScript.Environment (pattern (:->), pattern RecordT, function, kindType, DataDeclType (Data)) +import Language.PureScript.CoreFn.Pretty + ( prettyTypeStr, renderExprStr ) +import Language.PureScript.CoreFn.Ann (Ann) +import Language.PureScript.CoreFn.FromJSON () +import Data.Text qualified as T +import Data.List (find, elemIndex, sortOn, foldl') +import Language.PureScript.AST.Literals (Literal(..)) +import Data.Map qualified as M +import Language.PureScript.PSString (PSString) +import Language.PureScript.AST.SourcePos + ( pattern NullSourceAnn ) +import Control.Lens.IndexedPlated +import Control.Lens ( ix ) +import Language.PureScript.CoreFn.Convert.MonomorphizeV2 +import Language.PureScript.CoreFn.Convert.Monomorphize.Utils +import Data.Text (Text) +import Bound +import Data.Bifunctor (Bifunctor(first, second)) +import Control.Lens.Combinators (to) +import Language.PureScript.CoreFn (Binder(..), Module (..)) +import Data.Maybe (mapMaybe) +import Control.Lens.Operators +import Control.Lens (view) +import Control.Lens.Tuple +import Language.PureScript.CoreFn.Convert.IR hiding (stripQuantifiers) +import Language.PureScript.CoreFn.Convert.IR qualified as IR +import Language.PureScript.CoreFn.Utils hiding (stripQuantifiers) +import Control.Exception (throwIO) +import Debug.Trace +import Data.List (findIndex) +import Control.Monad (join, foldM) +import Language.PureScript.AST.Declarations (DataConstructorDeclaration (..)) +import Data.Map (Map) +import Language.PureScript.Constants.Prim qualified as C +import Language.PureScript.CoreFn.Convert.DesugarCore (desugarCore) +import Data.Void (Void) + +test :: FilePath -> Text -> IO (Exp WithoutObjects Ty (FVar Ty)) +test path decl = do + myMod <- decodeModuleIO path + Just myDecl <- pure $ findDeclBody decl myMod + case monomorphizeExpr myMod myDecl of + Left (MonoError msg ) -> throwIO $ userError $ "Couldn't monomorphize " <> T.unpack decl <> "\nReason:\n" <> msg + Right body -> case tryConvertExpr body of + Left convertErr -> throwIO $ userError convertErr + Right e -> do + putStrLn (ppExp e) + pure e + +data WithoutObjects + +type instance XAccessor WithoutObjects = Void +type instance XObjectUpdate WithoutObjects = Void +type instance XObjectLiteral WithoutObjects = Void + +prepPIR :: FilePath + -> Text + -> IO (Exp WithoutObjects Ty (FVar Ty), Map (ProperName 'TypeName) (DataDeclType, [(Text, Maybe SourceType)], [DataConstructorDeclaration])) +prepPIR path decl = do + myMod@Module{..} <- decodeModuleIO path + + desugaredExpr <- case findDeclBody decl myMod of + Nothing -> error "findDeclBody" + Just expr -> case desugarCore expr of + Right expr' -> do + putStrLn $ "desugarCore HERE: " <> IR.ppExp expr' + pure expr' + Left msg -> throwIO + $ userError + $ "Could not simplify " + <> T.unpack (runModuleName moduleName <> ".main") <> "\nReason:\n" <> msg + + case monomorphizeExpr myMod desugaredExpr of + Left (MonoError msg ) -> + throwIO + $ userError + $ "Couldn't monomorphize " + <> T.unpack (runModuleName moduleName <> ".main") <> "\nReason:\n" <> msg + Right body -> do + putStrLn (ppExp body) + throwIO $ userError "TODO: simplify objects" + -- case tryConvertExpr body of + -- Left convertErr -> throwIO $ userError convertErr + -- Right e -> do + -- putStrLn (ppExp e) + -- pure (e,moduleDataTypes) + +-- This gives us a way to report the exact location of the error (which may no longer correspond *at all* to +-- the location given in the SourcePos annotations due to inlining and monomorphization) +data TypeConvertError + = TypeConvertError (SourceType -> SourceType ) SourceType String + +type TyConvertM = Either TypeConvertError + +tryConvertType :: SourceType -> Either TypeConvertError Ty +tryConvertType = go id + where + go :: (SourceType -> SourceType) -> SourceType -> Either TypeConvertError Ty + go f t = case t of + RecordT fs -> + if isClosedRow fs + then do + let fields = rowListType <$> mkFieldMap fs + arity = M.size fields + fakeTName = mkFakeTName arity + types = M.elems fields + -- types = types' <> [foldl' srcTypeApp (srcTypeConstructor fakeTName) types'] -- the types applied to the ctor + ctorType = foldl' srcTypeApp (srcTypeConstructor fakeTName) types + go f ctorType + else Left $ TypeConvertError f t $ prettyTypeStr fs <> " is not a closed row. Last: " <> prettyTypeStr (rowLast fs) + TypeVar _ txt -> Right $ TyVar txt + TypeConstructor _ tn -> Right $ TyCon tn + TypeApp ann t1 t2 -> do + t2' <- go (f . TypeApp ann t1) t2 + t1' <- go (f . (\x -> TypeApp ann x t2)) t1 + pure $ TyApp t1' t2' + KindApp ann t1 t2 -> do + t2' <- go (f . KindApp ann t1) t2 + t1' <- go (f . (\x -> KindApp ann x t2)) t1 + pure $ KApp t1' t2' + ForAll ann vis var mbk inner skol -> do + let khole = f . (\x -> ForAll ann vis var (Just x) inner skol) + ihole = f . (\x -> ForAll ann vis var mbk x skol) + mbk' <- case mbk of + Nothing -> pure Nothing + Just k -> Just <$> go khole k + inner' <- go ihole inner + pure $ Forall vis var mbk' inner' skol + KindedType ann t1 t2 -> do + t2' <- go (f . KindedType ann t1) t2 + t1' <- go (f . (\x -> KindedType ann x t2)) t1 + pure $ KType t1' t2' + + other -> Left $ TypeConvertError f other $ "Unsupported type: " <> prettyTypeStr other + +data ExprConvertError + = ExprConvertError (Expr Ann -> Expr Ann) (Expr Ann) (Maybe TypeConvertError) String + +type ConvertM = Either ExprConvertError + +prettyErrorT :: TypeConvertError -> String +prettyErrorT (TypeConvertError g t msg1) + = "Error when converting types to final IR: " <> msg1 + <> "\nin type:\n " <> prettyTypeStr (g $ TypeVar NullSourceAnn "") + <> "\nin type component:\n " <> prettyTypeStr t + +prettyError :: ExprConvertError -> String +prettyError = \case + ExprConvertError f e Nothing msg -> "Error when converting expression: " <> msg <> "\n " + <> renderExprStr (f $ fakeVar "") + <> "\nin subexpression:\n " + <> renderExprStr e + ExprConvertError f e (Just (TypeConvertError g t msg1)) msg2 -> "Error when converting types: " <> msg1 <> "\n" <> msg2 <> "\n " + <> renderExprStr (f $ fakeVar "") + <> "\nin subexpression:\n " + <> renderExprStr e + <> "\nin type:\n " + <> prettyTypeStr (g $ TypeVar NullSourceAnn "") + <> "\nin type component:\n " + <> prettyTypeStr t + where + fakeVar :: Text -> Expr Ann + fakeVar t = Var nullAnn (srcTypeConstructor $ Qualified ByNullSourcePos (ProperName "ERROR!")) (Qualified ByNullSourcePos (Ident t)) + +tryConvertExprIO :: Expr Ann -> IO () +tryConvertExprIO = putStrLn . either id ppExp . tryConvertExpr + +tryConvertExpr :: Expr Ann -> Either String (Exp WithoutObjects Ty (FVar Ty)) +tryConvertExpr = first prettyError . tryConvertExpr' + +tryConvertExpr' :: Expr Ann -> Either ExprConvertError (Exp WithoutObjects Ty (FVar Ty)) +tryConvertExpr' = go id + where + go :: (Expr Ann -> Expr Ann) -> Expr Ann -> Either ExprConvertError (Exp WithoutObjects Ty (FVar Ty)) + go f expression = case expression of + Literal ann ty lit -> do + let lhole = f . Literal ann ty . ArrayLiteral . pure + ty' <- goType ty + tryConvertLit lhole lit >>= \case + Left desObj -> pure desObj + Right lit' -> pure $ LitE ty' lit' + Constructor _ ty tn cn fs -> do + ty' <- goType ty + pure $ CtorE ty' tn cn fs + Abs ann ty ident e -> do + ty' <- goType ty + ex <- go (f . Abs ann ty ident) e + let expr = abstract (matchVar (headArg ty') ident) ex + pure $ LamE ty' (BVar 0 (headArg ty') ident) expr + App ann e1 e2 -> do + e2' <- go (f . App ann e1) e2 + e1' <- go (f . (\x -> App ann x e2)) e1 + pure $ AppE e1' e2' + Case ann ty scrutinees alts -> do + ty' <- goType ty + scrutinees' <- goList (f . (\x -> Case ann ty [x] alts)) scrutinees + alts' <- traverse (goAlt (f . Case ann ty scrutinees . pure)) alts + pure $ CaseE ty' scrutinees' alts' + Let ann binds e -> do + rawBinds <- goBinds (f . (\x -> Let ann [x] e)) binds + e' <- go (f . Let ann binds) e + let allBoundIdents = fst <$> join rawBinds + abstr = abstract (abstractMany allBoundIdents) + bindEs = assembleBindEs [] rawBinds + bindings = mkBindings allBoundIdents + pure $ LetE bindings bindEs (abstr e') + xp@(Accessor _ ty lbl e) -> case desugarObjectAccessor ty lbl e of + Nothing -> Left $ ExprConvertError f xp Nothing "Failed to desugar Accessor" + Just desugE -> go f desugE + upd@(ObjectUpdate _ ty orig copF updF) -> case desugarObjectUpdate ty orig copF updF of + Nothing -> Left $ ExprConvertError f upd Nothing "Failed to desugar ObjectUpdate" + Just desugE -> go f desugE + Var _ ty (Qualified _ nm) -> do + ty' <- goType ty + pure . V $ FVar ty' nm + where + goAlt :: (CaseAlternative Ann -> Expr Ann) -> CaseAlternative Ann -> Either ExprConvertError (Alt WithoutObjects Ty (Exp WithoutObjects Ty) (FVar Ty)) + goAlt g (CaseAlternative binders result) = do + boundVars <- concat <$> traverse (getBoundVar result) binders + let pats = map toPat binders + let resultF = g . CaseAlternative binders + abstrE = abstract (abstractMany boundVars) + goResult resultF result >>= \case + Left _ges -> error "unrechable" + Right re -> pure $ UnguardedAlt (mkBindings boundVars) pats (abstrE re) + where + getBoundVar :: Either [(Expr Ann, Expr Ann)] (Expr Ann) -> Binder Ann -> ConvertM [FVar Ty] + getBoundVar body b = case b of + ConstructorBinder _ _ _ bs -> concat <$> traverse (getBoundVar body) bs + LiteralBinder _ (ArrayLiteral xs) -> concat <$> traverse (getBoundVar body) xs + LiteralBinder _ (ObjectLiteral fs) -> concat <$> traverse (getBoundVar body . snd) fs + VarBinder _ nm -> case body of + Right exbody -> case findBoundVar nm exbody of + Nothing -> pure [] -- probably should trace or warn at least + Just (t,_) -> do + ty' <- goType t + pure [FVar ty' nm] + Left fml -> do + let allResults = concatMap (\(x,y) -> [x,y]) fml + matchingVar = mapMaybe (findBoundVar nm) allResults + case matchingVar of + ((t,_):_) -> do + ty' <- goType t + pure [FVar ty' nm] + _ -> pure [] + _ -> pure [] + + goResult :: (Either [(Expr Ann, Expr Ann)] (Expr Ann) -> Expr Ann) + -> Either [(Expr Ann, Expr Ann)] (Expr Ann) + -> Either ExprConvertError (Either [(Exp WithoutObjects Ty (FVar Ty), Exp WithoutObjects Ty (FVar Ty))] (Exp WithoutObjects Ty (FVar Ty))) + goResult h = \case + Left exs -> do + exs' <- traverse (goGuarded (h . Left)) exs + pure (Left exs') + Right ex -> do + ex' <- go (h . Right) ex + pure (Right ex') + where + goGuarded cb (e1,e2) = do + e1' <- go (\x -> cb [(x,e2)]) e1 + e2' <- go (\x -> cb [(e1,x)]) e2 + pure (e1',e2') + + goBinds :: (Bind Ann -> Expr Ann) -> [Bind Ann] -> Either ExprConvertError [[(FVar Ty, Exp WithoutObjects Ty (FVar Ty))]] + goBinds _ [] = pure [] + goBinds g (b:bs) = case b of + NonRec ann ident expr -> do + ty' <- goType (exprType expr) + e' <- go (g . NonRec ann ident ) expr + rest <- goBinds g bs + pure $ [(FVar ty' ident,e')] : rest + -- TODO: Fix this to preserve recursivity (requires modifying the *LET* ctor of Exp) + Rec _xs -> do + let xs = map (\((ann,nm),e) -> NonRec ann nm e) _xs + xs' <- goBinds g xs + rest <- goBinds g bs + pure $ xs' <> rest + + allVars :: Expr Ann -> [(SourceType, Qualified Ident)] + allVars ex = ex ^.. icosmos @Context @(Expr Ann) M.empty . _Var . to (\(_,b,c) -> (b,c)) + + findBoundVar :: Ident -> Expr Ann -> Maybe (SourceType, Qualified Ident) + findBoundVar nm ex = find (goFind . snd) (allVars ex) + where + goFind = \case + Qualified (ByModuleName _) _ -> False + Qualified ByNullSourcePos _ -> False -- idk about this actually, guess we'll find out + Qualified (BySourcePos _) nm' -> nm == nm' + + goList :: (Expr Ann -> Expr Ann) -> [Expr Ann] -> Either ExprConvertError [Exp WithoutObjects Ty (FVar Ty)] + goList _ [] = pure [] + goList g (ex:exs) = do + e' <- go g ex + es' <- goList g exs + pure $ e' : es' + + -- ONLY USE THIS IN LAMBDA ABSTRACTIONS! + matchVar :: Ty -> Ident -> FVar Ty -> Maybe (BVar Ty) + matchVar t nm (FVar ty n') + | ty == t && nm == n' = Just (BVar 0 t nm) + | otherwise = Nothing + + tryConvertLit :: (Expr Ann -> Expr Ann) -> Literal (Expr Ann) -> Either ExprConvertError (Either (Exp WithoutObjects Ty (FVar Ty)) (Lit WithoutObjects (Exp WithoutObjects Ty (FVar Ty)))) + tryConvertLit cb = \case + NumericLiteral (Left i) -> pure . Right $ IntL i + NumericLiteral (Right d) -> pure . Right $ NumL d + StringLiteral pss -> pure . Right $ StringL pss + CharLiteral c -> pure . Right $ CharL c + BooleanLiteral b -> pure . Right $ BoolL b + ArrayLiteral xs -> Right . ArrayL <$> traverse (go cb) xs + ObjectLiteral fs' -> do -- TODO Maybe check for empty? I think that's a legal expr? + let fs = sortOn fst fs' + len = length fs + fakeCName = mkFakeCName len + fakeTName = mkFakeTName len + bareFields = snd <$> fs + types' = exprType <$> bareFields + types = types' <> [foldl' srcTypeApp (srcTypeConstructor fakeTName) types'] + ctorType = foldr1 function types + ctorExp = Constructor nullAnn ctorType (disqualify fakeTName) (disqualify fakeCName) [] + ctor <- assembleDesugaredObjectLit ctorExp ctorType bareFields + Left <$> go cb ctor + + goType :: SourceType -> Either ExprConvertError Ty + goType = catchTE . tryConvertType + + catchTE :: forall t. Either TypeConvertError t -> Either ExprConvertError t + catchTE = first ((\x -> ExprConvertError f expression x "Failed to convert type") . Just) + +assembleDesugaredObjectLit :: Expr Ann -> SourceType -> [Expr Ann] -> Either ExprConvertError (Expr Ann) +assembleDesugaredObjectLit expr (_ :-> b) (arg:args) = assembleDesugaredObjectLit (App nullAnn expr arg) b args +assembleDesugaredObjectLit expr _ [] = pure expr -- TODO better error +assembleDesugaredObjectLit _ _ _ = error "something went wrong in assembleDesugaredObjectLit" + +desugarObjectAccessor :: SourceType -> PSString -> Expr Ann -> Maybe (Expr Ann) +desugarObjectAccessor _ lbl e = do + traceM "desugarObjectAccesor" + RecordT _fs <- pure $ exprType e -- TODO check that it's actually a closed record? + let fs = M.toList (rowListType <$> mkFieldMap _fs) + len = length fs + fakeCName = mkFakeCName len + fakeTName = mkFakeTName len + types' = snd <$> fs + dummyNm = Ident "" + lblIx <- elemIndex lbl (fst <$> fs) + traceM $ "TYPES: " <> show (prettyTypeStr <$> types') + let fieldTy = types' !! lblIx -- if it's not there *something* should have caught it by now + let argBndrTemplate = replicate len (NullBinder nullAnn) & ix lblIx .~ VarBinder nullAnn dummyNm + ctorBndr = ConstructorBinder nullAnn fakeTName fakeCName argBndrTemplate + rhs = Var nullAnn fieldTy (Qualified ByNullSourcePos dummyNm) + altBranch = CaseAlternative [ctorBndr] $ Right rhs + -- the actual expression should get desugared after this (i hope?) + pure $ Case nullAnn fieldTy [e] [altBranch] + -- ctorBndr = ConstructorBinder + +-- I'm not really sure what the point of the copy fields is? TODO: Figure out what the point of them is +desugarObjectUpdate :: SourceType -> Expr Ann -> Maybe [PSString] -> [(PSString,Expr Ann)] -> Maybe (Expr Ann) +desugarObjectUpdate _ e _ updateFields = do + RecordT _fs <- pure $ exprType e + let updateMap = M.fromList updateFields + updateTypes = M.fromList $ second exprType <$> updateFields + origTypes = rowListType <$> mkFieldMap _fs + ts = updateTypes `M.union` origTypes + len = M.size ts + fakeCName = mkFakeCName len + fakeTName = mkFakeTName len + types' = M.elems ts + types = types' <> [foldl' srcTypeApp (srcTypeConstructor fakeTName) types'] + ctorType = foldr1 function types + + positioned = zip (M.keys ts) [0..] + + withPositioned :: forall x. (PSString -> Int -> x) -> [x] + withPositioned f = uncurry f <$> positioned + + argBndrTemplate = withPositioned $ \lbl i -> case M.lookup lbl updateMap of + Nothing -> VarBinder nullAnn . Ident $ " T.pack (show i) <> ">" + Just _ -> NullBinder nullAnn + + resultTemplate = withPositioned $ \lbl i -> case M.lookup lbl updateMap of + Nothing -> + let nm = Ident $ " T.pack (show i) <> ">" + in Var nullAnn (origTypes M.! lbl) (Qualified ByNullSourcePos nm) + Just expr -> expr + + ctorExp = Constructor nullAnn ctorType (disqualify fakeTName) (disqualify fakeCName) [] + + resultExpr = assembleDesugaredObjectLit ctorExp ctorType resultTemplate + + ctorBndr = ConstructorBinder nullAnn fakeTName fakeCName argBndrTemplate + case resultExpr of + Left err -> error $ prettyError err + Right res -> do + let altBranch = CaseAlternative [ctorBndr] $ Right res + pure $ Case nullAnn ctorType [e] [altBranch] + +isClosedRow :: SourceType -> Bool +isClosedRow t = case rowToList t of + (_,REmpty{}) -> True + (_,KindApp _ REmpty{} k) | eqType k kindType -> True + _ -> False + +rowLast :: SourceType -> SourceType +rowLast t = case rowToList t of + (_,r) -> r + +allTypes :: Expr Ann -> [SourceType] +allTypes e = e ^.. icosmos @Context @(Expr Ann) M.empty . to exprType + +-- TODO: Fuck these tuples, make real data types when more time + +mkTupleCtorData :: Int -> (ProperName 'ConstructorName,(ProperName 'TypeName,Int,[Ty])) +mkTupleCtorData n | n <= 0 = error "Don't try to make a 0-tuple" +mkTupleCtorData n = (cn,(tn,n,tys)) + where + cn = disqualify . mkFakeCName $ n + tn = disqualify . mkFakeTName $ n + tys = TyVar . ("~TUPLE_ARG_" <>) . T.pack . show <$> [1..n] + +_100TupleCtors :: CtorDict +_100TupleCtors = M.fromList $ mkTupleCtorData <$> [1..100] + +-- Don't normally like type syns in contexts like this but hlint will probably make this unreadable w/o them +type CtorDict = Map (ProperName 'ConstructorName) (ProperName 'TypeName,Int,[Ty]) +mkConstructorMap :: Map (ProperName 'TypeName) (DataDeclType,[(Text, Maybe SourceType)],[DataConstructorDeclaration]) + -> TyConvertM CtorDict +mkConstructorMap decls = M.union _100TupleCtors <$> foldM go M.empty (M.toList decls) + where + go :: Map (ProperName 'ConstructorName) (ProperName 'TypeName, Int, [Ty]) + -> (ProperName 'TypeName, (DataDeclType, [(Text, Maybe SourceType)],[DataConstructorDeclaration])) + -> TyConvertM (Map (ProperName 'ConstructorName) (ProperName 'TypeName, Int, [Ty])) + go acc (tyNm,(_declTy, _tyArgs, ctorDatas)) = do + ctors <- traverse extractCTorData ctorDatas + let indexedCTors = mkIndex <$> ctors + pure $ foldl' (\acc' (a,b,c,d) -> M.insert a (b,c,d) acc') acc indexedCTors + where + extractCTorData :: DataConstructorDeclaration -> TyConvertM (ProperName 'ConstructorName,ProperName 'TypeName,[Ty]) + extractCTorData (DataConstructorDeclaration _ ctorNm ctorFields) = do + fields' <- traverse (tryConvertType . snd) ctorFields + pure $ (ctorNm,tyNm,fields') + mkIndex :: (ProperName 'ConstructorName, ProperName 'TypeName, [Ty]) + -> (ProperName 'ConstructorName, ProperName 'TypeName, Int,[Ty]) + mkIndex (cn,tn,fs) = case findIndex (\DataConstructorDeclaration{..} -> dataCtorName == cn) ctorDatas of + Nothing -> error "couldn't find ctor name (impossible)" + Just i -> (cn,tn,i,fs) + +lookupSOP :: ProperName 'TypeName -> TyConDict -> Maybe [(Int,[Ty])] +lookupSOP nm dict = view _3 <$> M.lookup nm dict + +lookupArgs :: ProperName 'TypeName -> TyConDict -> Maybe [(Text,Maybe Ty)] +lookupArgs nm dict = view _2 <$> M.lookup nm dict + +mkTupleTyConData :: Int -> (ProperName 'TypeName,(DataDeclType,[(Text,Maybe Ty)],[(Int,[Ty])])) +mkTupleTyConData n = (tn,(Data,args,indices)) + where + tn = disqualify $ mkFakeTName n + vars = [1..n] <&> \x -> "~TUPLE_ARG_" <> T.pack (show x) + args = zip vars (replicate n (Just (TyCon C.Type))) + qualifier = Qualified (ByModuleName $ ModuleName "$GEN") . ProperName + indices = [(0,TyCon . qualifier <$> vars)] + +_100TupleTyCons :: TyConDict +_100TupleTyCons = M.fromList $ mkTupleTyConData <$> [1..100] + +type TyConDict = (Map (ProperName 'TypeName) (DataDeclType,[(Text,Maybe Ty)],[(Int,[Ty])])) +mkTyConMap :: Map (ProperName 'TypeName) (DataDeclType,[(Text, Maybe SourceType)],[DataConstructorDeclaration]) + -> TyConvertM (Map (ProperName 'TypeName) (DataDeclType,[(Text,Maybe Ty)],[(Int,[Ty])])) +mkTyConMap decls = M.union _100TupleTyCons <$> foldM go M.empty (M.toList decls) + where + go :: Map (ProperName 'TypeName) (DataDeclType,[(Text,Maybe Ty)],[(Int,[Ty])]) + -> (ProperName 'TypeName, (DataDeclType, [(Text, Maybe SourceType)],[DataConstructorDeclaration])) + -> TyConvertM (Map (ProperName 'TypeName) (DataDeclType,[(Text,Maybe Ty)],[(Int,[Ty])])) + go acc (tn,(declTy,tyArgs,ctorDatas)) = do + tyArgs' <- (traverse . traverse . traverse) tryConvertType tyArgs + indexedProducts <- zip [0..] <$> traverse (traverse (tryConvertType . snd) . dataCtorFields) ctorDatas + pure $ M.insert tn (declTy,tyArgs',indexedProducts) acc +-} diff --git a/src/Language/PureScript/CoreFn/Convert/IR.hs b/src/Language/PureScript/CoreFn/Convert/IR.hs new file mode 100644 index 000000000..aa5959f52 --- /dev/null +++ b/src/Language/PureScript/CoreFn/Convert/IR.hs @@ -0,0 +1,604 @@ +{-# OPTIONS_GHC -Wno-orphans #-} -- has to be here (more or less) +{-# OPTIONS_GHC -Werror #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DeriveTraversable, DeriveAnyClass #-} +{-# LANGUAGE InstanceSigs #-} +{-# LANGUAGE StandaloneDeriving #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE UndecidableInstances #-} + +module Language.PureScript.CoreFn.Convert.IR where + +import Prelude +import Language.PureScript.Names (Ident(..), Qualified (..), QualifiedBy (..), ProperNameType (..), ProperName(..), disqualify, runModuleName, showIdent, runIdent, moduleNameFromString, coerceProperName, showQualified) +import Language.PureScript.Types + ( SkolemScope, TypeVarVisibility (..), genPureName ) +import Language.PureScript.CoreFn (Binder(..), Literal (..)) +import Language.PureScript.CoreFn.FromJSON () +import Data.Text qualified as T +import Data.Map qualified as M +import Language.PureScript.PSString (PSString, prettyPrintString, decodeStringWithReplacement) +import Data.Text (Text) +import Bound +import Data.Kind qualified as GHC +import Control.Monad +import Data.Functor.Classes +import Data.Bifunctor (Bifunctor(first)) +import Data.Maybe (fromJust, fromMaybe) +import Text.Show.Deriving +import Prettyprinter +import Language.PureScript.Constants.Prim qualified as C +import Prettyprinter.Render.Text ( renderStrict ) +import Data.Map (Map) +import Control.Lens.TH (makePrisms) +import Bound.Scope (instantiateEither) +import Protolude.List (ordNub) +import Data.List (elemIndex, sortOn) +import Control.Lens (view,_2) +import Language.PureScript.CoreFn.TypeLike +import Data.Void (Void) +-- The final representation of types and terms, where all constructions that +-- *should* have been eliminated in previous steps are impossible +-- TODO: Make sure we error on exotic kinds +data Ty + = TyVar Text + | TyCon (Qualified (ProperName 'TypeName)) + | TyApp Ty Ty + | KApp Ty Ty + | Forall TypeVarVisibility Text (Maybe Ty) Ty (Maybe SkolemScope) + | KType Ty Ty + deriving (Show, Eq, Ord) + +pattern (:~>) :: Ty -> Ty -> Ty +pattern a :~> b = TyApp (TyApp (TyCon C.Function) a) b +infixr 0 :~> + +instance TypeLike Ty where + applyType = TyApp + + stripQuantifiers = \case + Forall vis var mk inner _ -> first ((vis,var,mk):) $ stripQuantifiers inner + other -> ([],other) + + funTy a b = a :~> b + + funArgTypes = init . splitFunTyParts + + replaceAllTypeVars = go [] where + go :: [Text] -> [(Text, Ty)] -> Ty -> Ty + go _ m (TyVar v) = fromMaybe (TyVar v) (v `lookup` m) + go bs m (TyApp t1 t2) = TyApp (go bs m t1) (go bs m t2) + go bs m (KApp t1 t2) = KApp (go bs m t1) (go bs m t2) + go bs m (Forall vis v mbK t sco) + | v `elem` keys = go bs (filter ((/= v) . fst) m) $ Forall vis v mbK' t sco + | v `elem` usedVars = + let v' = genPureName v (keys ++ bs ++ usedVars) + t' = go bs [(v, TyVar v')] t + in Forall vis v' mbK' (go (v' : bs) m t') sco + | otherwise = Forall vis v mbK' (go (v : bs) m t) sco + where + mbK' = go bs m <$> mbK + keys = map fst m + usedVars = concatMap (usedTypeVariables . snd) m + go bs m (KType t k) = KType (go bs m t) (go bs m k) + go _ _ ty = ty + + splitFunTyParts = \case + (a :~> b) -> a : splitFunTyParts b + t -> [t] + + quantify ty = foldr (\arg t -> Forall TypeVarInvisible arg Nothing t Nothing) ty $ freeTypeVariables ty + + instantiates var x (TyVar y) | y == var = Just x + instantiates var (TyApp t1 t2) (TyApp t1' t2') = case instantiates var t1 t1' of + Just x -> Just x + Nothing -> instantiates var t2 t2' + instantiates _ _ _ = Nothing + + freeTypeVariables = ordNub . fmap snd . sortOn fst . go 0 [] where + -- Tracks kind levels so that variables appearing in kind annotations are listed first. + go :: Int -> [Text] -> Ty -> [(Int, Text)] + go lvl bound (TyVar v) | v `notElem` bound = [(lvl, v)] + go lvl bound (TyApp t1 t2) = go lvl bound t1 ++ go lvl bound t2 + go lvl bound (KApp t1 t2) = go lvl bound t1 ++ go (lvl - 1) bound t2 + go lvl bound (Forall _ v mbK t _) = foldMap (go (lvl - 1) bound) mbK ++ go lvl (v : bound) t + go lvl bound (KType t k) = go lvl bound t ++ go (lvl - 1) bound k + go _ _ _ = [] + + usedTypeVariables = ordNub . go + where + go :: Ty -> [Text] + go (TyVar v) = [v] + go (TyApp t1 t2) = go t1 <> go t2 + go (KApp t1 t2) = go t1 <> go t2 + go (KType t1 t2) = go t1 <> go t2 + go (Forall _ _ _ inner _) = go inner + go (TyCon _) = error "iUsedTypeVariables: TODO: TyCon" -- not sure what it should be + + resultTy t = case snd $ stripQuantifiers t of + (_ :~> b) -> resultTy b + other -> other + +-- HACK: Need this for pretty printer, refactor later +class FuncType ty where + -- | Get first argument of a function, if function or act as identity otherwise + headArg :: ty -> ty + +instance FuncType Ty where + headArg t = case snd $ stripQuantifiers t of + (a :~> _) -> a + other -> other + +type Bindings ty = Map Int (FVar ty) + +-- A Bound variable. Serves as a bridge between the textual representation and the named de bruijn we'll need for PIR +data BVar ty = BVar Int ty Ident deriving (Show, Eq, Ord) -- maybe BVar Int (FVar ty) ?? + +data FVar ty = FVar ty (Qualified Ident) deriving (Show, Eq, Ord) + +data Lit x a + = IntL Integer + | NumL Double + | StringL PSString + | CharL Char + | BoolL Bool + | ArrayL [a] + | ConstArrayL [Lit x Void] + | ObjectL !(XObjectLiteral x) [(PSString, a)] + deriving (Functor, Foldable, Traversable) + +deriving instance (Show a, Show (XObjectLiteral x)) => Show (Lit x a) +deriving instance (Eq a, Eq (XObjectLiteral x)) => Eq (Lit x a) +deriving instance (Ord a, Ord (XObjectLiteral x)) => Ord (Lit x a) + +-- We're switching to a more "Haskell-like" representation (largely to avoid overlapping names) +data Pat x (f :: GHC.Type -> GHC.Type) a + = VarP Ident -- VarBinder + | WildP -- NullBinder + | AsP Ident (Pat x f a) -- NamedBinder + | LitP (Lit x (Pat x f a)) -- LiteralBinder + | ConP (Qualified (ProperName 'TypeName)) (Qualified (ProperName 'ConstructorName)) [Pat x f a] -- CTor binder + deriving (Functor, Foldable, Traversable) + +deriving instance (Show a, Show (XObjectLiteral x)) => Show (Pat x f a) +deriving instance (Eq a, Eq (XObjectLiteral x)) => Eq (Pat x f a) +deriving instance (Ord a, Ord (XObjectLiteral x)) => Ord (Pat x f a) + +data Alt x ty f a + = UnguardedAlt (Bindings ty) [Pat x f a] (Scope (BVar ty) f a) + deriving (Functor, Foldable, Traversable) + +deriving instance (Monad f, Show1 f, Show a, Show ty, Show (XObjectLiteral x)) => Show (Alt x ty f a) +deriving instance (Monad f, Eq1 f, Eq a, Eq ty, Eq (XObjectLiteral x)) => Eq (Alt x ty f a) +deriving instance (Monad f, Ord1 f, Ord a, Ord ty, Ord (XObjectLiteral x)) => Ord (Alt x ty f a) + +getPat :: Alt x ty f a -> [Pat x f a] +getPat = \case + UnguardedAlt _ ps _ -> ps + +-- idk if we really need the identifiers? +data BindE ty (f :: GHC.Type -> GHC.Type) a + = NonRecursive Ident (f a) + | Recursive [(Ident, f a)] + deriving (Eq,Ord,Show,Functor,Foldable,Traversable) + +flattenBind :: BindE ty f a -> [(Ident, f a)] +flattenBind = \case + NonRecursive i e -> [(i,e)] + Recursive xs -> xs + +type family XAccessor x +type family XObjectUpdate x +type family XObjectLiteral x + +data Exp x ty a + = V a -- let's see if this works + | LitE ty (Lit x (Exp x ty a)) + | CtorE ty (ProperName 'TypeName) (ProperName 'ConstructorName) [Ident] + | LamE ty (BVar ty) (Scope (BVar ty) (Exp x ty) a) + | AppE (Exp x ty a) (Exp x ty a) + | CaseE ty [Exp x ty a] [Alt x ty (Exp x ty) a] + | LetE (Bindings ty) [BindE ty (Exp x ty) a] (Scope (BVar ty) (Exp x ty) a) + | AccessorE !(XAccessor x) ty PSString (Exp x ty a) + | ObjectUpdateE !(XObjectUpdate x) ty (Exp x ty a) (Maybe [PSString]) [(PSString, Exp x ty a)] + deriving (Functor,Foldable,Traversable) + +deriving instance (Eq ty, Eq a, Eq (XAccessor x), Eq (XObjectUpdate x), Eq (XObjectLiteral x)) => Eq (Exp x ty a) + +instance Eq ty => Eq1 (Exp x ty) where + liftEq eq (V a) (V b) = eq a b + liftEq eq (LitE t1 l1) (LitE t2 l2) = t1 == t2 && liftEq (liftEq eq) l1 l2 + liftEq _ (CtorE t1 tn1 cn1 fs1) (CtorE t2 tn2 cn2 fs2) = t1 == t2 && tn1 == tn2 && cn1 == cn2 && fs1 == fs2 + liftEq eq (LamE t1 n1 e1) (LamE t2 n2 e2) = t1 == t2 && n1 == n2 && liftEq eq e1 e2 + liftEq eq (AppE l1 l2) (AppE r1 r2) = liftEq eq l1 r1 && liftEq eq l2 r2 + liftEq eq (CaseE t1 es1 as1) (CaseE t2 es2 as2) = t1 == t2 && liftEq (liftEq eq) es1 es2 && liftEq (liftEq eq) as1 as2 + liftEq eq (LetE n1 bs1 e1) (LetE n2 bs2 e2) = n1 == n2 && liftEq (liftEq eq) bs1 bs2 && liftEq eq e1 e2 + liftEq _ _ _ = False + +instance Eq1 (Lit x) where + liftEq _ (IntL i1) (IntL i2) = i1 == i2 + liftEq _ (NumL i1) (NumL i2) = i1 == i2 + liftEq _ (StringL i1) (StringL i2) = i1 == i2 + liftEq _ (CharL i1) (CharL i2) = i1 == i2 + liftEq _ (BoolL i1) (BoolL i2) = i1 == i2 + liftEq eq (ArrayL xs) (ArrayL ys) = liftEq eq xs ys + liftEq _ _ _ = False + +instance (Eq1 f, Monad f) => Eq1 (Pat x f) where + liftEq _ (VarP i1) (VarP i2) = i1 == i2 + liftEq _ WildP WildP = True + liftEq eq (AsP i1 p1) (AsP i2 p2) = i1 == i2 && liftEq eq p1 p2 + liftEq eq (ConP tn1 cn1 ps1) (ConP tn2 cn2 ps2) = tn1 == tn2 && cn1 == cn2 && liftEq (liftEq eq) ps1 ps2 + liftEq eq (LitP l1) (LitP l2) = liftEq (liftEq eq) l1 l2 + liftEq _ _ _ = False + +instance (Eq1 f) => Eq1 (BindE ty f) where + liftEq eq (NonRecursive i1 b1) (NonRecursive i2 b2) = i1 == i2 && liftEq eq b1 b2 + liftEq eq (Recursive xs) (Recursive ys) = go eq xs ys + where + go :: forall a b. (a -> b -> Bool) -> [(Ident, f a)] -> [(Ident, f b)] -> Bool + go f ((i1,x):xss) ((i2,y):yss) = i1 == i2 && liftEq f x y && go f xss yss + go _ [] [] = True + go _ _ _ = False + liftEq _ _ _ = False + +instance (Eq1 f, Monad f, Eq ty) => Eq1 (Alt x ty f) where + liftEq eq (UnguardedAlt n1 ps1 e1) (UnguardedAlt n2 ps2 e2) = n1 == n2 && liftEq (liftEq eq) ps1 ps2 && liftEq eq e1 e2 + +instance Applicative (Exp x ty) where + pure = V + (<*>) = ap + +instance Monad (Exp x ty) where + return = pure + V a >>= f = f a + CtorE t tn cn fs >>= _ = CtorE t tn cn fs + AppE e1 e2 >>= f = AppE (e1 >>= f) (e2 >>= f) + LamE t i e >>= f = LamE t i (e >>>= f) + LetE n bs e >>= f = LetE n (map (>>>= f) bs) (e >>>= f) + CaseE t es alts >>= f = CaseE t (map (\x -> x >>= f) es) (map (>>>= f) alts) + LitE t lit >>= f = LitE t $ goLit lit + where + goLit = \case + IntL i -> IntL i + NumL d -> NumL d + StringL str -> StringL str + CharL c -> CharL c + BoolL b -> BoolL b + ArrayL xs -> ArrayL $ map (\x -> x >>= f) xs + ConstArrayL lits -> ConstArrayL lits + ObjectL ext obj -> ObjectL ext $ map (\(field, x) -> (field, x >>= f)) obj + AccessorE ext ty field expr >>= f = AccessorE ext ty field (expr >>= f) + ObjectUpdateE ext ty expr toCopy toUpdate >>= f = + ObjectUpdateE ext ty (expr >>= f) toCopy (map (\(field, x) -> (field, x >>= f)) toUpdate) + +instance Bound (Pat x) where + VarP i >>>= _ = VarP i + WildP >>>= _ = WildP + AsP i p >>>= f = AsP i (p >>>= f) + ConP tn cn p >>>= f = ConP tn cn (map (>>>= f) p) + LitP litP >>>= f = LitP (goLit litP) + where + goLit = \case + IntL i -> IntL i + NumL d -> NumL d + StringL str -> StringL str + CharL c -> CharL c + BoolL b -> BoolL b + ConstArrayL lits -> ConstArrayL lits + ArrayL xs -> ArrayL $ map (\x -> x >>>= f) xs + ObjectL ext obj -> ObjectL ext $ map (\(field, x) -> (field, x >>>= f)) obj + +instance Bound (Alt x ty) where + UnguardedAlt i ps e >>>= f = UnguardedAlt i (map (>>>= f) ps) (e >>>= f) + +instance Bound (BindE ty) where + NonRecursive i e >>>= f = NonRecursive i $ e >>= f + Recursive xs >>>= f = Recursive $ go f xs + where + go :: forall a f c. Monad f => (a -> f c) -> [(Ident, f a)] -> [(Ident, f c)] + go _ [] = [] + go g ((i,e):rest) = + let e' = e >>= g + rest' = go g rest + in (i,e') : rest' + +instance Pretty (BVar ty) where + pretty (BVar n _t i) = pretty (showIdent i) <> pretty n -- <+> "::" <+> pretty t + +instance Pretty (FVar ty) where + pretty (FVar _t i) = pretty (showQualified showIdent i) -- <+> "::" <+> pretty t) + +instance Pretty Ty where + pretty = \case + TyVar t -> pretty t + TyCon (Qualified qb tn) -> case qb of + ByModuleName mn -> + let mn' = runModuleName mn + tn' = runProperName tn + in pretty mn' <> "." <> pretty tn' + _ -> pretty (runProperName tn) + TyApp t1 t2 -> goTypeApp t1 t2 + KApp t1 t2 -> pretty t1 <> ("@" <> pretty t2) + Forall vis var mk inner _ -> case stripQuantifiers inner of + (quantified,inner') -> goForall ((vis,var,mk): quantified) inner' + KType ty kind -> parens $ pretty ty <> " :: " <> pretty kind + where + goTypeApp :: forall ann. Ty -> Ty -> Doc ann + goTypeApp (TyApp f a) b + | f == TyCon C.Function = + let a' = pretty a + b' = pretty b + in hsep [a' <+> "->",b'] + | otherwise = + let f' = goTypeApp f a + b' = pretty b + in f' <+> b' + goTypeApp a b = hsep [pretty a, pretty b] + + goForall :: [(TypeVarVisibility,Text,Maybe Ty)] -> Ty -> Doc ann + goForall xs inner = + let boundVars = hsep $ renderBoundVar <$> xs + inner' = pretty inner + in "forall" <+> boundVars <> "." <+> inner' + where + renderBoundVar :: (TypeVarVisibility, Text, Maybe Ty) -> Doc ann + renderBoundVar (_, var, mk) = case mk of + Nothing -> pretty var + Just k -> parens (pretty var <+> "::" <+> pretty k) + +instance (Pretty a, Pretty ty, FuncType ty) => Pretty (Exp x ty a) where + pretty = \case + V x -> pretty x + LitE ty lit -> parens $ pretty lit <+> "::" <+> pretty ty + CtorE _ _ cname _ -> pretty $ runProperName cname + LamE ty bv body' -> + let unscoped = fromScope body' + in "\\" <> parens (align $ pretty bv <+> "::" <+> pretty (headArg ty)) + <+> "->" <> hardline + <> indent 2 (pretty unscoped) + appE@(AppE _ _) -> case unsafeAnalyzeApp appE of + (fun,args) -> + let applied = group . align . hsep $ parens . pretty <$> (fun:args) + in group . align $ parens applied + CaseE _ es alts -> + let scrutinees = group $ hsep (pretty <$> es) + branches = group . pretty <$> alts + in "case" <+> scrutinees <+> "of" + <+> hardline <+> indent 2 (vcat branches) + LetE _ bound e -> + let unscopedE = fromScope e + in align $ vcat [ + "let", + indent 2 . align . vcat $ pretty <$> bound, + "in" <+> align (pretty unscopedE) + ] + AccessorE _ _ field expr -> parens (pretty expr) <> dot <> pretty field + ObjectUpdateE _ _ _ _ _ -> "TODO: Implement ObjectUpdateE printer" + +instance (Pretty a, Pretty ty, FuncType ty) => Pretty (Alt x ty (Exp x ty) a) where + pretty = \case + UnguardedAlt _ ps body -> hcat (pretty <$> ps) <+> "->" <> + hardline <> indent 2 (pretty $ fromScope body) + +instance (Pretty b, Pretty a) => Pretty (Var b a) where + pretty = \case + B b -> pretty b + F a -> pretty a + +instance Pretty a => Pretty (Lit x a) where + pretty = \case + IntL i -> pretty i + NumL d -> pretty d + StringL pss -> pretty . T.unpack $ prettyPrintString pss + CharL c -> viaShow . show $ c + BoolL b -> if b then "true" else "false" + ConstArrayL xs -> list $ pretty <$> xs + ArrayL xs -> list $ pretty <$> xs + ObjectL _ obj -> encloseSep "{" "}" ", " + (map (\(field, expr) -> (pretty $ T.pack $ decodeStringWithReplacement field) <> ":" <+> pretty expr) obj) + +instance Pretty a => Pretty (Pat x (Exp x ty) a) where + pretty = \case + VarP i -> pretty (runIdent i) + WildP -> "_" + AsP i pat -> pretty (runIdent i) <> pretty pat + LitP lit -> case lit of + IntL i -> pretty i + NumL d -> pretty d + StringL pss -> pretty . T.unpack $ prettyPrintString pss + CharL c -> viaShow . show $ c + BoolL b -> if b then "true" else "false" + ConstArrayL xs -> list $ pretty <$> xs + ArrayL xs -> list $ pretty <$> xs + ObjectL _ _obj -> "TODO: Implement ObjectL pattern printer" + ConP cn _ ps -> pretty (runProperName . disqualify $ cn) <+> hsep (pretty <$> ps) + +instance (Pretty a, Pretty ty, FuncType ty, Pretty (Exp x ty a)) => Pretty (BindE ty (Exp x ty) a) where + pretty = \case + NonRecursive i e -> pretty (runIdent i) <+> "=" <+> pretty e + Recursive es -> + let go (ident,expr) = pretty (runIdent ident) <+> "=" <+> pretty expr + in align . vcat $ go <$> es + +ppExp :: (Pretty a, Pretty ty, FuncType ty) => Exp x ty a -> String +ppExp = T.unpack . renderStrict . layoutPretty defaultLayoutOptions . pretty + +ppTy :: Ty -> String +ppTy = T.unpack . renderStrict . layoutPretty defaultLayoutOptions . pretty + +unsafeAnalyzeApp :: forall x a ty. Exp x ty a -> (Exp x ty a, [Exp x ty a]) +unsafeAnalyzeApp e = fromJust $ (,appArgs e) <$> appFun e + where + appArgs :: Exp x ty a -> [Exp x ty a] + appArgs (AppE t1 t2) = appArgs t1 <> [t2] + appArgs _ = [] + + appFun :: Exp x ty a -> Maybe (Exp x ty a) + appFun (AppE t1 _) = go t1 + where + go (AppE tx _) = case appFun tx of + Nothing -> Just tx + Just tx' -> Just tx' + go other = Just other + appFun _ = Nothing + +expTy :: forall x t a. TypeLike t => (a -> Var (BVar t) (FVar t)) -> Exp x t a -> t +expTy f = \case + V x -> case f x of + B (BVar _ t _) -> t + F (FVar t _) -> t + LitE t _ -> t + CtorE t _ _ _ -> t + LamE t _ _ -> t + AppE e1 e2 -> appType f e1 e2 + CaseE t _ _ -> t + LetE _ _ e -> expTy' f e + AccessorE _ t _ _ -> t + ObjectUpdateE _ t _ _ _ -> t + +expTy' :: forall x t a. TypeLike t => (a -> Var (BVar t) (FVar t)) -> Scope (BVar t) (Exp x t) a -> t +expTy' f scoped = case instantiateEither (either (V . B) (V . F)) scoped of + V x -> case x >>= f of + B (BVar _ t _) -> t + F (FVar t _) -> t + LitE t _ -> t + CtorE t _ _ _ -> t + LamE t _ _ -> t + AppE e1 e2 -> appType (>>= f) e1 e2 + CaseE t _ _ -> t + LetE _ _ e -> expTy' (>>= f) e + AccessorE _ t _ _ -> t + ObjectUpdateE _ t _ _ _ -> t + +-- | Gets the type of an application expression. +-- (Name might be a bit confusing, does not apply types) +appType :: forall x t a. TypeLike t => (a -> Var (BVar t) (FVar t)) -> Exp x t a -> Exp x t a -> t +appType h fe ae = case stripQuantifiers funT of + ([],ft) -> + let numArgs = length argTypes + in foldl1 funTy . drop numArgs . splitFunTyParts $ ft + (xs,ft) -> + let funArgs = funArgTypes ft + dict = mkInstanceMap M.empty (view _2 <$> xs) argTypes funArgs + numArgs = length argTypes + in quantify + . foldl1 funTy + . drop numArgs + . splitFunTyParts + . replaceAllTypeVars (M.toList dict) + $ ft + where + (f,args) = appFunArgs fe ae + funT = expTy h f + argTypes = expTy h <$> args + + mkInstanceMap :: Map Text t -> [Text] -> [t] -> [t] -> Map Text t + mkInstanceMap acc [] _ _ = acc + mkInstanceMap acc _ [] _ = acc + mkInstanceMap acc _ _ [] = acc + mkInstanceMap acc (var:vars) (mt:mts) (pt:pts) = case instantiates var mt pt of + Nothing -> mkInstanceMap acc [var] mts pts + <> mkInstanceMap M.empty vars (mt:mts) (pt:pts) + Just t -> mkInstanceMap (M.insert var t acc) vars (mt:mts) (pt:pts) + +appFunArgs :: forall x ty a. Exp x ty a -> Exp x ty a -> (Exp x ty a, [Exp x ty a]) +appFunArgs f args = (appFun f, appArgs f args) + where + appArgs :: Exp x ty a -> Exp x ty a -> [Exp x ty a] + appArgs (AppE t1 t2) t3 = appArgs t1 t2 <> [t3] + appArgs _ t3 = [t3] + + appFun :: Exp x ty a -> Exp x ty a + appFun (AppE t1 _) = appFun t1 + appFun res = res + + +$(deriveShow1 ''BindE) + +instance (Show (XObjectLiteral x)) => Show1 (Lit x) where + liftShowsPrec = $(makeLiftShowsPrec ''Lit) + +instance (Show (XObjectLiteral x)) => Show1 (Pat x f) where + liftShowsPrec = $(makeLiftShowsPrec ''Pat) + +instance (Show ty, Show (XAccessor x), Show (XObjectUpdate x), Show (XObjectLiteral x)) => Show1 (Exp x ty) where + liftShowsPrec = $(makeLiftShowsPrec ''Exp) + +-- TH cannot derive it because `f` is used in last and second last field and some machinery doesn't like that +instance (Show ty, Show (XAccessor x), Show (XObjectUpdate x), Show (XObjectLiteral x)) => Show1 (Alt x ty (Exp x ty)) where + liftShowsPrec sp sl d (UnguardedAlt i ps e) + = showString "UnGuardedAlt " + . showsPrec d i + . showString " " + . showsPrec d (fmap (\x -> liftShowsPrec sp sl d x "") ps) + . showString " " + . liftShowsPrec sp sl d e + +deriving instance (Show a, Show ty, Show1 (Exp x ty), Show (XAccessor x), Show (XObjectUpdate x), Show (XObjectLiteral x)) => Show (Exp x ty a) + +makePrisms ''Ty +makePrisms ''Exp + +-- REVIEW: This *MIGHT* not be right. I'm not 1000% sure what the PS criteria for a mutually rec group are +-- First arg threads the FVars that correspond to the already-processed binds +-- through the rest of the conversion. I think that's right - earlier bindings +-- should be available to later bindings +assembleBindEs :: Eq ty => [FVar ty] -> [[(FVar ty ,Exp x ty (FVar ty))]] -> [BindE ty (Exp x ty) (FVar ty)] +assembleBindEs _ [] = [] +assembleBindEs dict ([]:rest) = assembleBindEs dict rest -- shouldn't happen but w/e +assembleBindEs dict ([(fv@(FVar _tx ix),e)]:rest) = + let dict' = fv:dict + -- abstr = abstract (abstractMany dict') + in NonRecursive (disqualify ix) e : assembleBindEs dict' rest +assembleBindEs dict (xsRec:rest) = + let (dict', recBind) = assembleRec dict xsRec + in recBind : assembleBindEs dict' rest + +assembleRec :: [FVar ty] -> [(FVar ty, Exp x ty (FVar ty))] -> ([FVar ty], BindE ty (Exp x ty) (FVar ty)) +assembleRec dict xs = + let dict' = dict <> (fst <$> xs) + -- abstr = abstract (abstractMany dict') + recBind = Recursive + . map (uncurry $ \(FVar _ ixx) xp -> (disqualify ixx, xp)) + $ xs + in (dict', recBind) + +mkBindings :: [FVar ty] -> Bindings ty +mkBindings = M.fromList . zip [0..] + +abstractMany :: Eq ty => [FVar ty] -> FVar ty -> Maybe (BVar ty) +abstractMany xs v@(FVar t i) = (\index -> BVar index t $ disqualify i) <$> elemIndex v xs + +toPat :: Binder ann -> Pat x (Exp x ty) (FVar ty) +toPat = \case + NullBinder _ -> WildP + VarBinder _ i -> VarP i + ConstructorBinder _ tn cn bs -> ConP tn cn $ map toPat bs + NamedBinder _ nm b -> AsP nm $ toPat b + LiteralBinder _ lp -> case lp of + NumericLiteral (Left i) -> LitP $ IntL i + NumericLiteral (Right d) -> LitP $ NumL d + StringLiteral pss -> LitP $ StringL pss + CharLiteral c -> LitP $ CharL c + BooleanLiteral b -> LitP $ BoolL b + ArrayLiteral as -> LitP $ ArrayL $ map toPat as + ObjectLiteral fs' -> do + -- this isn't right, we need to make sure the positions of the binders are correct, + -- since (I think?) you can use an Obj binder w/o using all of the fields + let fs = sortOn fst fs' + len = length fs + fakeCName = mkFakeCName len + fakeTName = mkFakeTName len + inner = map (toPat . snd) fs + in ConP fakeTName fakeCName inner + +mkFakeCName :: Int -> Qualified (ProperName 'ConstructorName) +mkFakeCName x = + Qualified + (ByModuleName $ moduleNameFromString "$GEN") + (ProperName $ "~TUPLE_" <> T.pack (show x)) + +mkFakeTName :: Int -> Qualified (ProperName 'TypeName) +mkFakeTName x = coerceProperName @_ @'TypeName <$> mkFakeCName x diff --git a/src/Language/PureScript/CoreFn/Convert/Monomorphize.hs b/src/Language/PureScript/CoreFn/Convert/Monomorphize.hs new file mode 100644 index 000000000..73b948979 --- /dev/null +++ b/src/Language/PureScript/CoreFn/Convert/Monomorphize.hs @@ -0,0 +1,599 @@ +{-# OPTIONS_GHC -Wno-orphans #-} -- has to be here (more or less) +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE MultiWayIf #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# HLINT ignore "Use if" #-} +module Language.PureScript.CoreFn.Convert.Monomorphize where + +{- +import Prelude +import Data.Bifunctor +import Data.Maybe + +import Language.PureScript.CoreFn.Ann (Ann) +import Language.PureScript.CoreFn.Expr (PurusType) +import Language.PureScript.CoreFn.Module ( Module(..) ) +import Language.PureScript.CoreFn.Convert.IR (Exp(..), FVar(..), Alt(..), Lit(..), BindE(..), ppExp, unsafeAnalyzeApp, expTy) +import Language.PureScript.Names (Ident(..), Qualified (..), QualifiedBy (..), pattern ByNullSourcePos, ModuleName (..)) +import Language.PureScript.Types + ( rowToList, RowListItem(..), SourceType, Type(..), replaceTypeVars, isMonoType ) +import Language.PureScript.CoreFn.Pretty.Common ( analyzeApp ) +import Language.PureScript.CoreFn.Desugar.Utils ( showIdent' ) +import Language.PureScript.Environment (pattern (:->), pattern ArrayT, pattern RecordT, function, getFunArgTy) +import Language.PureScript.CoreFn.Pretty (prettyTypeStr) +import Language.PureScript.CoreFn.FromJSON () +import Data.Aeson qualified as Aeson +import Data.Text qualified as T +import Data.List (find, foldl') +import Data.Map (Map) +import Data.Map qualified as M +import Language.PureScript.Label (Label(runLabel)) +import Language.PureScript.PSString (PSString, prettyPrintString) +import Language.PureScript.AST.SourcePos (SourceAnn, pattern NullSourceSpan) +import Data.Bitraversable (Bitraversable(bitraverse)) +import Control.Lens.IndexedPlated ( itransform, itransformM ) +import Control.Lens + ( Identity(runIdentity), + (<&>), + (&), + (^?), + preview, + (^.), + (.~), + Ixed(ix), view ) +import Control.Monad.RWS.Class (MonadReader(ask), gets, modify') +import Control.Monad.RWS (RWST(..)) +import Control.Monad.Except (throwError) +import Language.PureScript.CoreFn.Utils (Context, exprType, instantiates) +import Control.Exception +import Data.Text (Text) +import Debug.Trace (trace, traceM) +import Language.PureScript.CoreFn.Convert.DesugarCore (WithObjects, desugarCore) +import Bound (fromScope) +import Bound.Var (Var(..)) + +{- Instead of mutual recursion, return ADTs that describe the "next step" of the computation + +-} + +{- +trace :: String -> p2 -> p2 +trace _ x = x + +traceM :: forall m. Monad m => String -> m () +traceM _ = pure () +-} +-- hopefully a better API than the existing traversal machinery (which is kinda weak!) +-- Adapted from https://twanvl.nl/blog/haskell/traversing-syntax-trees + +-- TODO: better error messages +data MonoError + = MonoError Context String deriving (Show) + +note :: Context -> String -> Maybe b -> Monomorphizer b +note d err = \case + Nothing -> throwError $ MonoError d err + Just x -> pure x + +-- ok we need monads +data MonoState = MonoState { + {- Original Identifier -> Type -> (Fresh Ident, Expr) + -} + visited :: Map Ident (Map SourceType (Ident, Exp WithObjects PurusType (FVar PurusType))), + unique :: Int +} +-- TODO: Logging, make a more useful state than S.Set Ident +type Monomorphizer a = RWST (ModuleName, [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)]) () MonoState (Either MonoError) a +type Monomorphizer' a = RWST (ModuleName, [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)]) () MonoState Identity (Maybe a) + +type IR_Decl = BindE PurusType (Exp WithObjects PurusType) (FVar PurusType) + +defInstantiate scoped = instantiateEither (either (V . B) (V . F)) scoped + +hoist1 :: + MonoState -> + Monomorphizer a -> + RWST ( ModuleName + , [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)]) + () + MonoState + Identity + (Maybe a) +hoist1 st act = RWST $ \r s -> f (runRWST act r s) + where + f :: Either MonoError (a, MonoState, ()) -> Identity (Maybe a, MonoState, ()) + f = \case + Left (MonoError d msg) -> do + traceM $ "MonoError: " <> msg <> ":\n" <> "Context: " <> show d + pure (Nothing,st,()) + Right (x,st',_) -> pure (Just x, st', ()) + +monomorphizeExpr :: + Module IR_Decl Ann -> + Exp WithObjects PurusType (FVar PurusType) -> + Either MonoError (Exp WithObjects PurusType (FVar PurusType)) +monomorphizeExpr m@Module{..} expr = + runRWST (monomorphizeA M.empty expr) (moduleName,moduleDecls) (MonoState M.empty 0) & \case + Left err -> Left err + Right (a,_,_) -> Right a + +monomorphizeMain :: + Module IR_Decl Ann -> + Maybe (Exp WithObjects PurusType (FVar PurusType)) +monomorphizeMain Module{..} = runMono g + where + emptySt = MonoState M.empty 0 + + g = monomorphizeB M.empty mainE + + monomorphizeB :: + Context -> + Exp WithObjects PurusType (FVar PurusType) -> + Monomorphizer' (Exp WithObjects PurusType (FVar PurusType)) + monomorphizeB d e = hoist1 emptySt (monomorphizeA d e) + + (mainE,otherDecls) = partitionDecls moduleDecls + + runMono :: RWST (ModuleName,[BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)]) () MonoState Identity a -> a + runMono act = case runIdentity (runRWST act (moduleName,otherDecls) (MonoState M.empty 0)) of + (a,_,_) -> a + +monomorphizeMain' :: + Module IR_Decl Ann -> + Either MonoError (Exp WithObjects PurusType (FVar PurusType)) +monomorphizeMain' Module{..} = g + where + g = runMono $ itransformM monomorphizeA M.empty mainE + + (mainE,otherDecls) = partitionDecls moduleDecls + + runMono :: RWST (ModuleName,[BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)]) () MonoState (Either MonoError) a -> Either MonoError a + runMono act = case runRWST act (moduleName,otherDecls) (MonoState M.empty 0) of + Left err -> Left err + Right (a,_,_) -> Right a + +decodeModuleIO :: FilePath -> IO (Module IR_Decl Ann) +decodeModuleIO path = Aeson.eitherDecodeFileStrict' path >>= \case + Left err -> throwIO $ userError err + Right modx -> pure modx + +getModName :: Monomorphizer ModuleName +getModName = ask <&> fst + +getModBinds :: Monomorphizer [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)] +getModBinds = ask <&> snd + +freshen :: Ident -> Monomorphizer Ident +freshen ident = do + u <- gets unique + modify' $ \(MonoState v _) -> MonoState v (u + 1) + let uTxt = T.pack (show u) + case ident of + Ident t -> pure $ Ident $ t <> "_$$" <> uTxt + GenIdent (Just t) i -> pure $ GenIdent (Just $ t <> "_$$" <> uTxt) i -- we only care about a unique ord property for the maps + GenIdent Nothing i -> pure $ GenIdent (Just $ "var_$$" <> uTxt) i + -- other two shouldn't exist at this stage + other -> pure other + +checkVisited :: Ident -> SourceType -> Monomorphizer (Maybe (Ident,Exp WithObjects PurusType (FVar PurusType))) +checkVisited ident st = gets (preview (ix ident . ix st) . visited) + +markVisited :: Ident -> SourceType -> Exp WithObjects PurusType (FVar PurusType) -> Monomorphizer Ident +markVisited ident st e = do + v <- gets visited + newIdent <- freshen ident + let v' = v & ix ident . ix st .~ (newIdent,e) + modify' $ \(MonoState _ u) -> MonoState v' u + pure newIdent + +-- returns (main,rest) +-- NOTE: Assumes main isn't part of a recursive binding group (it really shouldn't be?) +partitionDecls :: + [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)] -> + ( Exp WithObjects PurusType (FVar PurusType) + , [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)]) +partitionDecls bs = first fromJust $ foldr go (Nothing,[]) bs + where + go :: BindE PurusType (Exp WithObjects PurusType) (FVar PurusType) -> (Maybe (Exp WithObjects PurusType (FVar PurusType)), [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)]) -> (Maybe (Exp WithObjects PurusType (FVar PurusType)), [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)]) + go b acc = case b of + nonrec@(NonRecursive ident expr) -> case ident of + Ident "main" -> first (const $ Just expr) acc + _ -> second (nonrec:) acc + other -> second (other:) acc + +stripQuantifiers :: SourceType -> SourceType +stripQuantifiers = \case + ForAll _ _ _ _ inner _ -> stripQuantifiers inner + other -> other + +getResult :: SourceType -> SourceType +getResult (_ :-> b) = getResult b +getResult other = other + +findDeclBody :: Text -> Module IR_Decl Ann -> Maybe (Exp WithObjects PurusType (FVar PurusType)) +findDeclBody nm Module{..} = case findInlineDeclGroup (Ident nm) moduleDecls of + Nothing -> Nothing + Just decl -> case decl of + NonRecursive _ e -> Just e + Recursive xs -> snd <$> find (\x -> snd (fst x) == Ident nm) xs + +findInlineDeclGroup :: + Ident -> + [BindE PurusType (Exp x ty) a] -> + Maybe (BindE PurusType (Exp x ty) a) +findInlineDeclGroup _ [] = Nothing +findInlineDeclGroup ident (NonRecursive ident' expr:rest) + | ident == ident' = Just $ NonRecursive ident' expr + | otherwise = findInlineDeclGroup ident rest +findInlineDeclGroup ident (Recursive xs:rest) = case find (\x -> snd (fst x) == ident) xs of + Nothing -> findInlineDeclGroup ident rest + -- idk if we need to specialize the whole group? + Just _ -> Just (Recursive xs) + +monomorphizeA :: + Context -> + Exp WithObjects PurusType (FVar PurusType) -> + Monomorphizer (Exp WithObjects PurusType (FVar PurusType)) +monomorphizeA d xpr = trace ("monomorphizeA " <> "\n " <> ppExp xpr) $ case xpr of + app@(AppE _ arg) -> do + let (f,args) = unsafeAnalyzeApp app + traceM $ "FUN: " <> ppExp f + traceM $ "ARGS: " <> show (ppExp <$> args) + let types = concatMap (toArgs . exprType) args + traceM $ "ARG TYPES:" <> show (prettyTypeStr <$> types) + -- maybe trace or check that the types match? + -- need to re-quantify? not sure. CHECK! + + if isBuiltin f + then pure app + else either (uncurry gLet) id <$> handleFunction d f args + other -> pure other + where + isMonomorphizedVar :: Exp WithObjects PurusType (FVar PurusType) -> Bool + isMonomorphizedVar (V (FVar sty _)) = stripQuantifiers sty == sty + +isBuiltin :: forall x. Exp x PurusType (FVar PurusType) -> Bool +isBuiltin (V (FVar vTy (Qualified (ByModuleName (ModuleName "Builtin")) _))) = True +isBuiltin _ = False + +gLet :: + [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)] -> + Exp WithObjects PurusType (FVar PurusType) -> + Exp WithObjects PurusType (FVar PurusType) +gLet binds e = LetE binds e + +nameShadows :: Context -> Ident -> Bool +nameShadows cxt iden = isJust $ M.lookup iden cxt + +unsafeApply :: + Exp WithObjects PurusType (FVar PurusType) -> + [Exp WithObjects PurusType (FVar PurusType)] -> + Exp WithObjects PurusType (FVar PurusType) +unsafeApply e (arg:args)= case expTy F e of + (a :-> b) -> unsafeApply (AppE e arg) args + other -> Prelude.error $ "boom: " <> prettyTypeStr other +unsafeApply e [] = e + + +handleFunction :: Context + -> Exp WithObjects PurusType (FVar PurusType) + -> [Exp WithObjects PurusType (FVar PurusType)] -- TODO: List could be empty? + -> Monomorphizer (Either ([BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)], Exp WithObjects PurusType (FVar PurusType)) (Exp WithObjects PurusType (FVar PurusType))) +-- handleFunction d exp args | isBuiltin exp = trace ("handleFunction: Builtin") $ pure . Right $ unsafeApply exp args +handleFunction _ e [] = trace ("handleFunction FIN: " <> ppExp e) $ pure (pure e) +handleFunction d expr@(LamE (ForAll _ _ var _ inner _) ident body'') (arg:args) = do + traceM ("handleFunction abs:\n " <> ppExp expr <> "\n " <> show (ppExp <$> (arg:args))) + let t = exprType arg + traceM $ prettyTypeStr t + let polyArgT = getFunArgTy inner + -- WRONG! Probably need to check all of the args at once + doInstantiate = case instantiates var t polyArgT of + Just tx -> replaceTypeVars var tx + Nothing -> id + body' = updateVarTy d ident t body'' + cxt = M.insert ident t d + handleFunction cxt body' args >>= \case + Left (binds,body) -> do + let bodyT = exprType body + funT = doInstantiate $ function t bodyT + e' = Abs ann funT ident body + pure $ Left (binds, App nullAnn e' arg) + Right body -> do + let bodyT = exprType body + funT = doInstantiate $ function t bodyT + e' = Abs ann funT ident body + pure $ Right $ App nullAnn e' arg -- Abs ann (function t bodyT) ident body) +handleFunction d v@(V (FVar ty qn)) es = trace ("handleFunction VarGo: " <> ppExp v) $ do + traceM (ppExp v) + traceM (show $ ppExp <$> es) + e' <- either (uncurry gLet) id <$> inlineAs d ty qn + handleFunction d e' es +handleFunction d e es | isMonoType (exprType e) = pure . Right $ unsafeApply e es +handleFunction d e es = throwError $ MonoError d + $ "Error in handleFunction:\n " + <> ppExp e + <> "\n " <> show (ppExp <$> es) + <> "\n is not an abstraction or variable" + +-- I *think* all CTors should be translated to functions at this point? +-- TODO: We can make sure the variables are well-scoped too +updateVarTy :: Context -> Ident -> PurusType -> Exp WithObjects PurusType (FVar PurusType) -> Exp WithObjects PurusType (FVar PurusType) +updateVarTy d ident ty = itransform goVar d + where + goVar :: Context -> Exp WithObjects PurusType (FVar PurusType) -> Exp WithObjects PurusType (FVar PurusType) + goVar _d expr = undefined {- -case expr ^? _Var of + Just (ann,_,Qualified q@(BySourcePos _) varId) | varId == ident -> Var ann ty (Qualified q ident) + _ -> expr +-} + +updateFreeVar :: M.Map Ident (Ident,SourceType) -> Context -> Exp WithObjects PurusType (FVar PurusType) -> Exp WithObjects PurusType (FVar PurusType) +updateFreeVar dict _ expr = undefined {- + + case expr ^? _Var of + Just (_,_,Qualified (ByModuleName _) varId) -> case M.lookup varId dict of + Nothing -> expr + Just (newId,newType) -> Var nullAnn newType (Qualified ByNullSourcePos newId) + _ -> expr +-} +updateFreeVars :: Map Ident (Ident, SourceType) -> Context -> Exp WithObjects PurusType (FVar PurusType) -> Exp WithObjects PurusType (FVar PurusType) +updateFreeVars dict = itransform (updateFreeVar dict) + +-- doesn't change types! +renameBoundVar :: Ident -> Ident -> Context -> Exp WithObjects PurusType (FVar PurusType) -> Exp WithObjects PurusType (FVar PurusType) +renameBoundVar old new _ e = undefined {- + case e ^? _Var of + Just (ann,ty,Qualified (BySourcePos sp) varId) | varId == old -> Var ann ty (Qualified (BySourcePos sp) new) + _ -> e +-} +renameBoundVars :: Ident -> Ident -> Context -> Exp WithObjects PurusType (FVar PurusType) -> Exp WithObjects PurusType (FVar PurusType) +renameBoundVars old new = itransform (renameBoundVar old new) + -- \/ Replace with ([BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)], Exp WithObjects PurusType (FVar PurusType)) +inlineAs :: + Context -> + PurusType -> + Qualified Ident -> + Monomorphizer (Either + ( [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)] + , Exp WithObjects PurusType (FVar PurusType)) + (Exp WithObjects PurusType (FVar PurusType))) +-- TODO: Review whether this has any purpose here \/ +inlineAs _ ty nm@(Qualified (ByModuleName (ModuleName "Builtin")) idnt) = trace ("inlineAs BUILTIN:\n " <> "IDENT: " <> showIdent' idnt <> "\n TYPE: " <> prettyTypeStr ty) + $ pure . Right $ undefined -- Var nullAnn ty nm +-- TODO: Probably can inline locally bound variables? FIX: Keep track of local name bindings +inlineAs d _ (Qualified (BySourcePos _) ident) = throwError $ MonoError d $ "can't inline bound variable " <> showIdent' ident +inlineAs d ty qmn@(Qualified (ByModuleName mn') ident) = trace ("inlineAs: " <> showIdent' ident <> " :: " <> prettyTypeStr ty) $ ask >>= \(mn,modDict) -> + if | mn == mn' -> do + let msg = "Couldn't find a declaration with identifier " <> showIdent' ident <> " to inline as " <> prettyTypeStr ty + note d msg (findInlineDeclGroup ident modDict) >>= \case + NonRecursive _ e -> do + e' <- monomorphizeWithType ty d e + pure . Right $ e' + Recursive xs -> do + traceM $ "RECURSIVE GROUP:\n" <> concatMap (\((_,xId),t) -> showIdent' xId <> " :: " <> ppExp t <> "\n") xs + let msg' = "Target expression with identifier " <> showIdent' ident <> " not found in mutually recursive group" + (targIdent,targExpr) <- note d msg' $ find (\x -> fst x == ident) (first snd <$> xs) -- has to be there + fresh <- freshen targIdent + let initialRecDict = M.singleton targIdent (fresh,ty,targExpr) + dict <- collectRecBinds initialRecDict ty d targExpr + let renameMap = (\(i,t,_) -> (i,t)) <$> dict + bindingMap = M.elems dict + cxt = foldl' (\acc (idx,tyx)-> M.insert idx tyx acc) d $ (\(a,b,_) -> (a,b)) <$> M.elems dict + binds <- traverse (\(newId,newTy,oldE) -> makeBind renameMap cxt newId newTy oldE) bindingMap + case M.lookup targIdent renameMap of + Just (newId,newTy) -> pure $ Left (binds, undefined ) {- -Var nullAnn newTy (Qualified ByNullSourcePos newId)) -} + Nothing -> throwError + $ MonoError d + $ "Couldn't inline " <> showIdent' ident <> " - identifier didn't appear in collected bindings:\n " <> show renameMap + -- TODO: This is a temporary hack to get builtins working w/o a real linker. + | otherwise -> throwError $ MonoError d "Imports aren't supported!" + where + makeBind :: Map Ident (Ident,SourceType) -> Context -> Ident -> SourceType -> Exp WithObjects PurusType (FVar PurusType) -> Monomorphizer (BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)) + makeBind renameDict depth newIdent t e = trace ("makeBind: " <> showIdent' newIdent) $ do + e' <- updateFreeVars renameDict depth <$> monomorphizeWithType t depth e + pure $ NonRecursive newIdent e' + + -- Find a declaration body in the *module* scope + findDeclarationBody :: Ident -> Monomorphizer (Maybe (Exp WithObjects PurusType (FVar PurusType))) + findDeclarationBody nm = go <$> getModBinds + where + go :: [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)] -> Maybe (Exp WithObjects PurusType (FVar PurusType)) + go [] = Nothing + go (b:bs) = case b of + NonRecursive nm' e -> if nm' == nm then Just e else go bs + Recursive xs -> case find (\x -> snd (fst x) == nm) xs of + Nothing -> go bs + Just ((_,_),e) -> Just e + + {- RECURSIVE BINDINGS + + First, we need to walk the target expression and collect a list of all of the used + bindings and the type that they must be when monomorphized, and the new identifier for their + monomorphized/instantiated version. (We *don't* change anything here) + -} + collectMany :: Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType)) -> PurusType -> Context -> [Exp WithObjects PurusType (FVar PurusType)] -> Monomorphizer (Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType))) + collectMany acc _ _ [] = trace "collectMany" $ pure acc + collectMany acc t dx (x:xs) = do + xBinds <- collectRecBinds acc t dx x + let acc' = acc <> xBinds + collectMany acc' t d xs + + collectRecFieldBinds :: Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType)) + -> M.Map PSString (RowListItem SourceAnn) + -> [(PSString, Exp WithObjects PurusType (FVar PurusType))] + -> Monomorphizer (Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType))) + collectRecFieldBinds visited _ [] = pure visited + collectRecFieldBinds visited cxt ((lbl,e):rest) = trace "collectRecFieldBinds" $ do + RowListItem{..} <- note d ("No type for field with label " <> T.unpack (prettyPrintString lbl) <> " when collecting record binds") + $ M.lookup lbl cxt + this <- collectRecBinds visited rowListType d e + collectRecFieldBinds (visited <> this) cxt rest + + collectFun :: Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType)) + -> Context + -> Exp WithObjects PurusType (FVar PurusType) + -> [SourceType] + -> Monomorphizer (Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType))) + collectFun visited _ e [t] = trace ("collectFun FIN:\n " <> ppExp e <> " :: " <> prettyTypeStr t) $ do + rest <- collectRecBinds visited t d e + pure $ visited <> rest + collectFun visited dx e@(LamE (ForAll{}) idx body'') (t:ts) = trace ("collectFun:\n " <> ppExp e <> "\n " <> prettyTypeStr t <> "\n" <> show ts) $ do + let body' = updateVarTy d idx t body'' + cxt = M.insert idx t dx + collectFun visited cxt body' ts + + collectFun visited dx (V (FVar _ (Qualified (ByModuleName _) nm))) (t:ts)= trace ("collectFun VAR: " <> showIdent' nm) $ do + case M.lookup nm visited of + Nothing -> do + let t' = foldr1 function (t:ts) + msg = "Couldn't find a declaration with identifier " <> showIdent' nm <> " to inline as " <> prettyTypeStr t + declBody <- note dx msg =<< findDeclarationBody nm + freshNm <- freshen nm + let visited' = M.insert nm (freshNm,t',declBody) visited + collectRecBinds visited' t' d declBody + Just _ -> pure visited + + collectFun _ dx e _ = throwError $ MonoError dx $ "Unexpected expression in collectFun:\n " <> ppExp e + + collectRecBinds :: + Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType)) -> + PurusType -> + Context -> + Exp WithObjects PurusType (FVar PurusType) -> + Monomorphizer (Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType))) + collectRecBinds visited t dx e = trace ("collectRecBinds:\n " <> ppExp e <> "\n " <> prettyTypeStr t) $ case e of + LitE _ (ArrayL arr) -> trace "crbARRAYLIT" $ case t of + ArrayT inner -> do + innerBinds <- collectMany visited inner dx arr + pure $ visited <> innerBinds + _ -> throwError $ MonoError dx ("Failed to collect recursive binds: " <> prettyTypeStr t <> " is not an Array type") + LitE _ (ObjectL _ fs) -> trace "crbOBJLIT" $ case t of + RecordT fields -> do + let fieldMap = mkFieldMap fields + innerBinds <- collectRecFieldBinds visited fieldMap fs + pure $ visited <> innerBinds + _ -> throwError $ MonoError dx ("Failed to collect recursive binds: " <> prettyTypeStr t <> " is not a Record type") + LitE _ _ -> trace "crbLIT" $ pure visited + CtorE _ _ _ _ -> trace "crbCTOR" $ pure visited + ObjectUpdateE _ _ _ _ updateFields -> trace "crbOBJUPDATE" $ case t of + RecordT fields -> do + let fieldMap = mkFieldMap fields + -- idk. do we need to do something to the original expression or is this always sufficient? + innerBinds <- collectRecFieldBinds visited fieldMap updateFields + pure $ visited <> innerBinds + _ -> throwError $ MonoError dx ("Failed to collect recursive binds: " <> prettyTypeStr t <> " is not a Record type") + AccessorE _ _ _ _ -> trace "crbACCSR" $ pure visited -- idk. given (x.a :: t) we can't say what x is + absE@(LamE _ _ _) -> trace ("crbABS TOARGS: " <> prettyTypeStr t) $ collectFun visited dx absE (toArgs t) + app@(AppE _ e2) -> trace "crbAPP" $ do + (f,args) <- note dx ("Not an App: " <> ppExp app) $ analyzeApp app + let types = (exprType <$> args) <> [t] + funBinds' <- collectFun visited dx f types -- collectRecBinds visited funTy d e1 + let funBinds = visited <> funBinds' + argBinds <- collectRecBinds funBinds (head types) dx e2 + pure $ funBinds <> argBinds + V (FVar _ (Qualified (ByModuleName _) nm)) -> trace ("crbVAR: " <> showIdent' nm) $ case M.lookup nm visited of + Nothing -> findDeclarationBody nm >>= \case + Nothing -> throwError $ MonoError dx $ "No declaration correponding to name " <> showIdent' nm <> " found in the module" + Just ex -> do + freshNm <- freshen nm + let this = (freshNm,t,ex) + pure $ M.insert nm this visited + Just _ -> pure visited -- might not be right, might need to check that the types are equal? ugh keeping track of scope is a nightmare + V (FVar _ (Qualified _ nm)) -> trace ("crbVAR_: " <> showIdent' nm) $ pure visited + CaseE _ _ alts -> trace "crbCASE" $ do + let flatAlts = concatMap extractAndFlattenAlts alts + aInner <- collectMany visited t dx flatAlts + pure $ visited <> aInner + LetE _ _ ex -> + -- not sure abt this + collectRecBinds visited t dx ex + + +-- TODO: Remove? +extractAndFlattenAlts :: Alt x ty (Exp x ty) a -> [Exp WithObjects PurusType (FVar PurusType)] +extractAndFlattenAlts (UnguardedAlt _ _ res) = [res] + + +-- I think this one actually requires case analysis? dunno how to do it w/ the lenses in less space (w/o having prisms for types which seems dumb?) +-- This *forces* the expression to have the provided type (and returns nothing if it cannot safely do that) +monomorphizeWithType :: + PurusType -> + Context -> + Exp WithObjects PurusType (FVar PurusType) -> + Monomorphizer (Exp WithObjects PurusType (FVar PurusType)) +monomorphizeWithType ty d expr + | exprType expr == ty = pure expr + | otherwise = trace ("monomorphizeWithType:\n " <> ppExp expr <> "\n " <> prettyTypeStr ty) $ case expr of + LitE ty (ArrayL arr) -> case ty of + ArrayT inner -> LitE ty . ArrayL <$> traverse (monomorphizeWithType inner d) arr + _ -> throwError $ MonoError d ("Failed to collect recursive binds: " <> prettyTypeStr ty <> " is not a Record type") + + LitE _ (ObjectL ext fs) -> case ty of + RecordT fields -> do + let fieldMap = mkFieldMap fields + LitE ty . ObjectL ext <$> monomorphizeFieldsWithTypes fieldMap fs + _ -> throwError $ MonoError d ("Failed to collect recursive binds: " <> prettyTypeStr ty <> " is not a Record type") + + LitE ty lit -> pure $ LitE ty lit + + CtorE _ tName cName fs -> pure $ CtorE ty tName cName fs + + ObjectUpdateE ext _ orig copyFields updateFields -> case ty of + RecordT fields -> do + let fieldMap = mkFieldMap fields + -- idk. do we need to do something to the original expression or is this always sufficient? + updateFields' <- monomorphizeFieldsWithTypes fieldMap updateFields + pure $ ObjectUpdateE ext ty orig copyFields updateFields' + _ -> throwError $ MonoError d ("Failed to collect recursive binds: " <> prettyTypeStr ty <> " is not a Record type") + + AccessorE ext _ str e -> pure $ AccessorE ext ty str e -- idk? + fun@(LamE _ ident body) -> trace ("MTABs:\n " <> ppExp fun <> " :: " <> prettyTypeStr ty) $ do + case ty of + (a :-> b) -> case nameShadows d ident of + False -> do + let cxt = M.insert ident a d + body' <- monomorphizeWithType b cxt $ updateVarTy cxt ident a body + pure $ LamE ty ident body' + True -> do + freshIdent <- freshen ident + let body' = renameBoundVar ident freshIdent d $ updateVarTy d ident a body + cxt = M.insert freshIdent a d + body'' <- monomorphizeWithType b cxt body' + error "TODO" + -- pure $ Abs nullAnn ty freshIdent body'' + _ -> throwError $ MonoError d "Abs isn't a function" + + app@(AppE _ e2) -> trace ("MTAPP:\n " <> ppExp app) $ do + (f,args) <- note d ("Not an app: " <> ppExp app) $ analyzeApp app + let types = (exprType <$> args) <> [ty] + e1' <- either (uncurry gLet) id <$> handleFunction d f args + pure $ AppE e1' e2 + + V a -> pure $ V a -- idk + + CaseE _ scrut alts -> error "TODO: wtf?" + -- let f = monomorphizeWithType ty d + -- -- goAlt :: Alt WithObjects PurusType -> Monomorphizer (CaseAlternative Ann) + -- goAlt (CaseAlternative binders results) = + -- CaseAlternative binders <$> bitraverse (traverse (bitraverse f f)) f results + -- in Case a ty scrut <$> traverse goAlt alts + + LetE a binds e -> LetE a binds <$> monomorphizeWithType ty d e + where + monomorphizeFieldsWithTypes :: M.Map PSString (RowListItem SourceAnn) -> [(PSString, Exp WithObjects PurusType (FVar PurusType))] -> Monomorphizer [(PSString, Exp WithObjects PurusType (FVar PurusType))] + monomorphizeFieldsWithTypes _ [] = pure [] + monomorphizeFieldsWithTypes cxt ((lbl,e):rest) = do + RowListItem{..} <- note d ("No type for field with label " <> T.unpack (prettyPrintString lbl) <> " when monomorphizing record") + $ M.lookup lbl cxt + rest' <- monomorphizeFieldsWithTypes cxt rest + e' <- monomorphizeWithType rowListType d e + pure $ (lbl,e') : rest' + +mkFieldMap :: SourceType -> M.Map PSString (RowListItem SourceAnn) +mkFieldMap fs = M.fromList $ (\x -> (runLabel (rowListLabel x),x)) <$> (fst . rowToList $ fs) + +toArgs :: SourceType -> [SourceType] +toArgs = \case + (a :-> b) -> a : toArgs b + other -> [other] +-} diff --git a/src/Language/PureScript/CoreFn/Convert/Monomorphize/Utils.hs b/src/Language/PureScript/CoreFn/Convert/Monomorphize/Utils.hs new file mode 100644 index 000000000..94364874f --- /dev/null +++ b/src/Language/PureScript/CoreFn/Convert/Monomorphize/Utils.hs @@ -0,0 +1,324 @@ +{-# OPTIONS_GHC -Wno-orphans #-} -- has to be here (more or less) +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE InstanceSigs #-} +{-# LANGUAGE PartialTypeSignatures #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# HLINT ignore "Use camelCase" #-} + +module Language.PureScript.CoreFn.Convert.Monomorphize.Utils where + +import Prelude + +import Language.PureScript.CoreFn.Expr (PurusType, Bind) +import Language.PureScript.CoreFn.Convert.IR (_V, Exp(..), FVar(..), BindE(..), BVar (..), flattenBind, abstractMany, mkBindings, Alt (..), Lit (..), expTy) +import Language.PureScript.Names (Ident(..), ModuleName (..), QualifiedBy (..), Qualified (..), pattern ByNullSourcePos) +import Language.PureScript.Types + ( SourceType, RowListItem (..), rowToList ) +import Language.PureScript.CoreFn.FromJSON () +import Data.Text qualified as T +import Data.Map (Map) +import Data.Map qualified as M +import Control.Lens ( (<&>), (^?) ) +import Control.Monad.RWS.Class (gets, modify', MonadReader (..)) +import Control.Monad.RWS (RWST(..)) +import Control.Monad.Except (throwError) +import Data.Text (Text) +import Bound.Var (Var(..)) +import Bound.Scope (Scope (..), abstractEither, toScope, fromScope, mapScope, mapBound) +import Data.Bifunctor (Bifunctor (..)) +import Data.List (find) +import Control.Lens.Plated ( transform, Plated(..) ) +import Language.PureScript.Environment (pattern (:->)) +import Language.PureScript.CoreFn.Pretty (prettyTypeStr) +import Language.PureScript.AST.SourcePos ( SourceAnn ) +import Language.PureScript.PSString (PSString) +import Language.PureScript.Label (Label(runLabel)) +import Language.PureScript.CoreFn.Module ( Module(..) ) +import Language.PureScript.CoreFn.Ann ( Ann ) +import Language.PureScript.CoreFn.Convert.DesugarCore + ( WithObjects ) +import Data.Aeson qualified as Aeson +import GHC.IO (throwIO) + +type IR_Decl = BindE PurusType (Exp WithObjects PurusType) (FVar PurusType) + +{- Monomorphizer monad & related utilities -} + +-- TODO: better error messages +newtype MonoError + = MonoError String deriving (Show) + +-- Just a newtype over `Int` +newtype MonoState = MonoState { + unique :: Int +} + +-- Reads (ModuleName,ModuleDecls), writes nothing (...yet), State is a newtype over Int for fresh names & etc +type Monomorphizer a = RWST (ModuleName, [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)]) () MonoState (Either MonoError) a + +getModName :: Monomorphizer ModuleName +getModName = ask <&> fst + +getModBinds :: Monomorphizer [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)] +getModBinds = ask <&> snd + +note :: String -> Maybe b -> Monomorphizer b +note err = \case + Nothing -> throwError $ MonoError err + Just x -> pure x + +freshen :: Ident -> Monomorphizer Ident +freshen ident = do + u <- gets unique + modify' $ \(MonoState _) -> MonoState (u + 1) + let uTxt = T.pack (show u) + case ident of + Ident t -> pure $ Ident $ t <> "_$$" <> uTxt + GenIdent (Just t) i -> pure $ GenIdent (Just $ t <> "_$$" <> uTxt) i -- we only care about a unique ord property for the maps + GenIdent Nothing i -> pure $ GenIdent (Just $ "var_$$" <> uTxt) i + -- other two shouldn't exist at this stage + other -> pure other + +freshBVar :: t -> Monomorphizer (BVar t) +freshBVar t = do + u <- gets unique + modify' $ \(MonoState _) -> MonoState (u + 1) + let gIdent = Ident $ T.pack ("x_$$" <> show u) + pure $ BVar u t gIdent + +{- + Misc utils for constructing/analyzing expressions +-} + +qualifyNull :: Ident -> Qualified Ident +qualifyNull = Qualified ByNullSourcePos + +-- Construct a Let expression from a list of BindEs and a scoped body +gLet :: + [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)] -> + Scope (BVar PurusType) (Exp WithObjects PurusType) (FVar PurusType) -> + Exp WithObjects PurusType (FVar PurusType) +gLet binds e = LetE bindings binds $ abstractEither abstr e' + where + e' = fromScope e + bindings = mkBindings allBoundIdents + allBoundIdents = uncurry (flip FVar . qualifyNull) <$> second (expTy F) <$> concatMap flattenBind binds + + abstr :: Var (BVar PurusType) (FVar PurusType) -> Either (BVar PurusType) (FVar PurusType) + abstr = \case + B bv -> Left bv + F fv -> case abstractMany allBoundIdents fv of + Nothing -> Right fv + Just bv -> Left bv + +-- Tools for updating variable types/names + +-- REVIEW: Is this right? Do we really want to update bound & free var types at the same time like this? +updateVarTyS :: forall x t + . BVar t + -> t + -> Scope (BVar t) (Exp x t) (FVar t) + -> Scope (BVar t) (Exp x t) (FVar t) +updateVarTyS (BVar ix _ ident) ty scoped = mapScope goBound goFree scoped + where + goBound :: BVar t -> BVar t + goBound bv@(BVar bvIx _ bvIdent) + | bvIx == ix && bvIdent == ident = BVar bvIx ty ident + | otherwise = bv + + goFree :: FVar t -> FVar t + goFree fv@(FVar _ (Qualified q@(BySourcePos _) varId)) + | varId == ident = FVar ty (Qualified q varId) + | otherwise = fv + goFree other = other + + +-- doesn't change types! +renameBoundVar :: Ident + -> Ident + -> Scope (BVar t) (Exp WithObjects t) (FVar t) + -> Scope (BVar t) (Exp WithObjects t) (FVar t) +renameBoundVar old new = mapBound $ \case + BVar bvIx bvTy bvIdent | bvIdent == old -> BVar bvIx bvTy new + other -> other + + +{- Given a function and a list of arguments that hopefully + match the type & number of the args in the functions signature, + apply the function to all of the arguments. + + TODO: Eventually we shouldn't need this but it's useful to throw errors + while debugging if we get something that's not a function +-} +unsafeApply :: + Exp WithObjects PurusType (FVar PurusType) -> + [Exp WithObjects PurusType (FVar PurusType)] -> + Exp WithObjects PurusType (FVar PurusType) +unsafeApply e (arg:args)= case expTy F e of + (_ :-> _) -> unsafeApply (AppE e arg) args + other -> Prelude.error $ "Unexpected argument to unsafeApply:" <> prettyTypeStr other +unsafeApply e [] = e + +{- Find the declaration *group* to which a given identifier belongs. +-} +findInlineDeclGroup :: + Ident -> + [BindE PurusType (Exp x ty) a] -> + Maybe (BindE PurusType (Exp x ty) a) +findInlineDeclGroup _ [] = Nothing +findInlineDeclGroup ident (NonRecursive ident' expr:rest) + | ident == ident' = Just $ NonRecursive ident' expr + | otherwise = findInlineDeclGroup ident rest +findInlineDeclGroup ident (Recursive xs:rest) = case find (\x -> fst x == ident) xs of + Nothing -> findInlineDeclGroup ident rest + Just _ -> Just (Recursive xs) + +{- Find the body of a declaration with the given name in the given module. +-} +findDeclBody :: Text + -> Module IR_Decl Ann + -> Maybe (Exp WithObjects PurusType (FVar PurusType)) +findDeclBody nm Module{..} = case findInlineDeclGroup (Ident nm) moduleDecls of + Nothing -> Nothing + Just decl -> case decl of + NonRecursive _ e -> Just e + Recursive xs -> snd <$> find (\x -> fst x == Ident nm) xs + +{- Turns a Row Type into a Map of field names to Row item data. + + NOTE: Be sure to unwrap the enclosing record if you're working w/ a + record type. +-} +mkFieldMap :: SourceType -> M.Map PSString (RowListItem SourceAnn) +mkFieldMap fs = M.fromList $ (\x -> (runLabel (rowListLabel x),x)) <$> (fst . rowToList $ fs) + +-- TODO: Doesn't have much of a purpose after the IR rework +extractAndFlattenAlts :: Alt x t (Exp x t) a -> [Scope (BVar t) (Exp x t) a] +extractAndFlattenAlts (UnguardedAlt _ _ res) = [res] + + +{- Updates the identifier and type of free variables using the provided Map + + Note that this erases original source position information, since it is meant to be + used during inlining (and ergo the original source position may no longer be + accurate or meaningful, e.g. in generated code) +-} +updateFreeVars :: Map Ident (Ident, SourceType) + -> Exp WithObjects PurusType (FVar PurusType) + -> Exp WithObjects PurusType (FVar PurusType) +updateFreeVars dict = transform updateFreeVar + where + updateFreeVar :: Exp WithObjects PurusType (FVar PurusType) -> Exp WithObjects PurusType (FVar PurusType) + updateFreeVar expr = case expr ^? _V of + Just (FVar _ (Qualified (ByModuleName _) varId)) -> case M.lookup varId dict of + Nothing -> expr + Just (newId,newType) -> V (FVar newType (Qualified ByNullSourcePos newId)) + _ -> expr + + +{- IO utility. Reads a CoreFn module from a source file. Probably this should be somewhere else? + +-} +decodeModuleIO :: FilePath -> IO (Module (Bind Ann) Ann) +decodeModuleIO path = Aeson.eitherDecodeFileStrict' path >>= \case + Left err -> throwIO $ userError err + Right modx -> pure modx + +{- + Bound utils +-} +transverseScopeAndVariables :: + (Monad exp, Traversable exp, Applicative f) => + (exp a -> f fvar1) -> + (Var bvar1 fvar1 -> exp (Var bvar2 fvar2)) -> + Scope bvar1 exp a -> + f (Scope bvar2 exp fvar2) +transverseScopeAndVariables f g expr = toScope . (g =<<) <$> traverse (traverse f) (unscope expr) + +{- Like `transverseScope` but not polymorphic in the `a` and allows + type changing. +-} +transverseScopeViaExp :: Applicative f + => (Exp x t a -> f (Exp x t b)) + -> Scope (BVar t) (Exp x t) a + -> f (Scope (BVar t) (Exp x t) b) +transverseScopeViaExp f scope + = let fromScoped = fromScope scope + sequenced = sequence fromScoped + traversed = traverse f sequenced + hm = sequence <$> traversed + in toScope <$> hm + +{- Surprisingly this is useful. We often want to ignore bound variables + when traversing the AST (esp during inlining, where they don't + matter at all). +-} +transverseScopeViaExp' :: (Exp x t a -> b) + -> Scope (BVar t) (Exp x t) a + -> Var (BVar t) b +transverseScopeViaExp' f scope + = let fromScoped = fromScope scope + sequenced = sequence fromScoped + in f <$> sequenced + +{- Mashup of `foldM` and `transverseScope`. +-} +foldMScopeViaExp :: Monad f + => b + -> (b -> Exp x t a -> f b) + -> [Scope (BVar t) (Exp x t) a] + -> f b +foldMScopeViaExp e _ [] = pure e +foldMScopeViaExp e f (x:xs) = case transverseScopeViaExp' (f e) x of + B _ -> foldMScopeViaExp e f xs + F act -> do + e' <- act + foldMScopeViaExp e' f xs + + +{- Useful for transform/rewrite/cosmos/etc -} +instance Plated (Exp x t a) where + plate = go + where + go :: forall f + . ( Applicative f) + => (Exp x t a -> f (Exp x t a)) + -> Exp x t a + -> f (Exp x t a) + go tfun = \case + LamE t bv e -> LamE t bv <$> helper e + CaseE t es alts -> + let goAlt :: Alt x t (Exp x t) a -> f (Alt x t (Exp x t) a) + goAlt (UnguardedAlt bs pats scoped) = UnguardedAlt bs pats <$> helper scoped + in CaseE t <$> traverse tfun es <*> traverse goAlt alts + LetE binds decls scoped -> + let goDecls :: BindE t (Exp x t) a -> f (BindE t (Exp x t) a) + goDecls = \case + NonRecursive ident expr -> + NonRecursive ident <$> tfun expr + Recursive xs -> + Recursive <$> traverse (\(i,x) -> (i,) <$> tfun x) xs + in LetE binds <$> traverse goDecls decls <*> helper scoped + AppE e1 e2 -> AppE <$> tfun e1 <*> tfun e2 + AccessorE x t pss e -> AccessorE x t pss <$> tfun e + ObjectUpdateE x t e cf fs -> (\e' fs' -> ObjectUpdateE x t e' cf fs') + <$> tfun e + <*> traverse (\(nm,expr) -> (nm,) <$> tfun expr) fs + LitE t lit -> LitE t <$> traverseLit lit + other -> tfun other + where + traverseLit :: Lit x (Exp x t a) + -> f (Lit x (Exp x t a)) + traverseLit = \case + IntL i -> pure $ IntL i + NumL d -> pure $ NumL d + StringL str -> pure $ StringL str + CharL char -> pure $ CharL char + BoolL b -> pure $ BoolL b + ArrayL xs -> ArrayL <$> traverse tfun xs + ConstArrayL xs -> ConstArrayL <$> pure xs + ObjectL x fs -> ObjectL x <$> traverse (\(str,e) -> (str,) <$> tfun e) fs + + helper :: Scope (BVar t) (Exp x t) a -> f (Scope (BVar t) (Exp x t) a) + helper = transverseScopeViaExp tfun diff --git a/src/Language/PureScript/CoreFn/Convert/MonomorphizeV2.hs b/src/Language/PureScript/CoreFn/Convert/MonomorphizeV2.hs new file mode 100644 index 000000000..93cdaba0a --- /dev/null +++ b/src/Language/PureScript/CoreFn/Convert/MonomorphizeV2.hs @@ -0,0 +1,440 @@ +{-# OPTIONS_GHC -Wno-orphans #-} -- has to be here (more or less) +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# HLINT ignore "Use if" #-} +module Language.PureScript.CoreFn.Convert.MonomorphizeV2 where + +import Prelude + +import Language.PureScript.CoreFn.Ann (Ann) +import Language.PureScript.CoreFn.Expr (PurusType) +import Language.PureScript.CoreFn.Module ( Module(..) ) +import Language.PureScript.CoreFn.Convert.IR + ( Exp(..), + FVar(..), + Lit(..), + BindE(..), + ppExp, + unsafeAnalyzeApp, + BVar(..), + expTy, + expTy', + FuncType(..), + Alt(..), + Alt ) +import Language.PureScript.Names (Ident(..), Qualified (..), QualifiedBy (..), ModuleName (..), showQualified, showIdent) +import Language.PureScript.Types + ( RowListItem(..), SourceType, Type(..), replaceTypeVars, isMonoType ) +import Language.PureScript.CoreFn.Desugar.Utils ( showIdent' ) +import Language.PureScript.Environment (pattern (:->), pattern ArrayT, pattern RecordT, function, getFunArgTy) +import Language.PureScript.CoreFn.Pretty (prettyTypeStr) +import Language.PureScript.CoreFn.FromJSON () +import Data.Text qualified as T +import Data.List (find) +import Data.Map (Map) +import Data.Map qualified as M +import Language.PureScript.PSString (PSString, prettyPrintString) +import Language.PureScript.AST.SourcePos (SourceAnn) +import Control.Lens + ( (&) ) +import Control.Monad (foldM) +import Control.Monad.RWS.Class (MonadReader(ask)) +import Control.Monad.RWS (RWST(..)) +import Control.Monad.Except (throwError) +import Debug.Trace (trace, traceM) +import Language.PureScript.CoreFn.Convert.DesugarCore +import Bound.Var (Var(..)) +import Bound.Scope (mapBound) +import Language.PureScript.CoreFn.TypeLike + ( TypeLike(splitFunTyParts, instantiates) ) +import Language.PureScript.CoreFn.Convert.Monomorphize.Utils + +import Data.Text (Text) +import GHC.IO (throwIO) + +{- Function for quickly testing/debugging monomorphization -} + +testMono :: FilePath -> Text -> IO () +testMono path decl = do + myModCoreFn <- decodeModuleIO path + myMod <- either (throwIO . userError) pure $ desugarCoreModule myModCoreFn + Just myDecl <- pure $ findDeclBody decl myMod + case runMonomorphize myMod myDecl of + Left (MonoError msg ) -> throwIO $ userError $ "Couldn't monomorphize " <> T.unpack decl <> "\nReason:\n" <> msg + Right body -> do + putStrLn $ "MONO RESULT: \n" <> ppExp body + -- pure unscopedBody + +{- This is the top-level entry point for monomorphization. Typically, + you will search the module for a 'main' decl and use its + body as the Exp argument. +-} +runMonomorphize :: + Module IR_Decl Ann -> + Exp WithObjects PurusType (FVar PurusType) -> + Either MonoError (Exp WithObjects PurusType (FVar PurusType)) +runMonomorphize Module{..} expr = + runRWST (monomorphize expr) (moduleName,moduleDecls) (MonoState 0) & \case + Left err -> Left err + Right (a,_,_) -> Right a + +{- Entry point for inlining monomorphization. + + Broadly, we deduce the monomorphic type for a polymorphic function + by looking at the arguments the function is applied to. Without + arguments, we cannot deduce the monomorphic type at all, and so + this function is `pure` if the provided expression is anything other than + than an `AppE` + + +-} +monomorphize :: + Exp WithObjects PurusType (FVar PurusType) -> + Monomorphizer (Exp WithObjects PurusType (FVar PurusType)) +monomorphize xpr = trace ("monomorphize " <> "\n " <> ppExp xpr) $ case xpr of + app@(AppE _ _) -> do + -- First, we split the + let (f,args) = unsafeAnalyzeApp app + traceM $ "FUN: " <> ppExp f + traceM $ "ARGS: " <> show (ppExp <$> args) + let types = concatMap (splitFunTyParts . expTy F) args + traceM $ "ARG TYPES:" <> show (prettyTypeStr <$> types) + + if isBuiltin f + then pure app + else handleFunction f args + other -> trace ("monomorphize: other: " <> ppExp other) $ pure other + where + -- Builtins shouldn't be inlined because they can't be. + -- TODO/REVIEW: Figure out whether it's necessary to *monomorphize* + -- polymorphic builtins. (Trivial to implement if needed) + isBuiltin = \case + V (FVar _ (Qualified (ByModuleName (ModuleName "Builtin")) _ )) -> True + _ -> False + +{- "Control flow" for the inlining monomorphizer. + + The first argument is a polymorphic function or identifier that + refers to a polymorphic function. + + The second argument is the ordered list of argument to which that + polymorphic function is applied in the `AppE` which was initially + passed to `monomorphize`. + + Will fail if it is passed anything other than a polymorphic function or a + free variable. (Or an already-monomorphized expression) + + NOTE: The order of the cases matters here! Don't move them around haphazardly. +-} +handleFunction :: Exp WithObjects PurusType (FVar PurusType) + -> [Exp WithObjects PurusType (FVar PurusType)] -- TODO: List could be empty? + -> Monomorphizer (Exp WithObjects PurusType (FVar PurusType)) +-- If we don't have any argument types, the only thing we can do is return the original expression. +handleFunction e [] = trace ("handleFunction FIN: " <> ppExp e) $ pure e +{- If we have an explicit polymorphic lambda & argument types, we look at the argument types one-by-one + and check whether those types allow us to deduce the type to which the TyVar bound by the Forall in + the lambda's type ought to be instantiated. (See the `instantiates` function) +-} +handleFunction expr@(LamE (ForAll _ _ var _ inner _) bv@(BVar bvIx _ bvIdent) body'') (arg:args) = do + traceM ("handleFunction abs:\n " <> ppExp expr) + let t = expTy F arg -- get the type of the first expression to which the function is applied + traceM $ prettyTypeStr t + let polyArgT = getFunArgTy inner -- get the (possibly polymorphic) type of the first arg in the function's signature + -- Get the (type) instantiation for the bound var, the (possibly) monomorphic type of the arg expr, + -- and the (possibly) polymorphic type of the function's first arg + -- REVIEW: Can we do all of the arguments at once? + doInstantiate :: SourceType -> SourceType + doInstantiate = case instantiates var t polyArgT of + Just tx -> replaceTypeVars var tx + Nothing -> id + body' = updateVarTyS bv t body'' -- update the type of the variable bound by the lambda in the body of the expression + body <- transverseScopeViaExp (flip handleFunction args) body' -- recurse on the body, with the rest of the arguments + let bodyT = expTy' F body + funT = doInstantiate $ function t bodyT + firstArgT = headArg funT + e' = LamE funT (BVar bvIx firstArgT bvIdent) body + pure $ AppE e' arg -- Put the app back together. (Remember, the params to this function come from a deconstructed AppE) +{- If we have a free variable, we attempt to inline the variable (without altering the type) + and then call `handleFunction` on the inlined expression with the same argument types +-} +handleFunction v@(V (FVar ty qn)) es = trace ("handleFunction VarGo: " <> ppExp v) $ do + e' <- inlineAs ty qn + handleFunction e' es +{- If the function parameter is monomorphic then we rebuild the initial AppE and return it. +-} +handleFunction e es | isMonoType (expTy F e) = trace ("handleFunction isMono: " <> ppExp e) $ pure $ unsafeApply e es +-- Anything else is an error. +handleFunction e es = throwError $ MonoError + $ "Error in handleFunction:\n " + <> ppExp e + <> "\n " <> show (ppExp <$> es) + <> "\n is not an abstraction or variable" + +{- | Monomorphizing inliner. Looks up the provided + identifier in the module context (TODO: linker that lets us support multiple modules) + and attempts to forcibly assign the provided type to that expression, then + inlines the monomorphized expression. + + Inlines and monomorphizes recursively, so that all free variables in the expression being + inlined are monomorphized to the appropriate type and themselves inlined. (I.e. inlines + everything and monomorphizes everything to the maximum extend possible) +-} +inlineAs :: + PurusType -> + Qualified Ident -> + Monomorphizer (Exp WithObjects PurusType (FVar PurusType)) +-- TODO/REVIEW: Check whether this has any purpose here \/ +inlineAs ty = \case + nm@(Qualified (ByModuleName (ModuleName "Builtin")) _ ) -> do + traceM ("inlineAs BUILTIN: " <> T.unpack (showQualified showIdent nm)) + pure $ V (FVar ty nm) + -- TODO: Linker so we can make this work no matter what the source module is + (Qualified (ByModuleName mn') ident) -> trace ("inlineAs: " <> showIdent' ident <> " :: " <> prettyTypeStr ty) $ ask >>= \(mn,modDict) -> + if mn == mn' then do + let msg = "Couldn't find a declaration with identifier " <> showIdent' ident <> " to inline as " <> prettyTypeStr ty + note msg (findInlineDeclGroup ident modDict) >>= \case + NonRecursive _ e -> monomorphizeWithType ty e + Recursive xs -> do + let msg' = "Target expression with identifier " <> showIdent' ident <> " not found in mutually recursive group" + (targIdent,targExpr) <- note msg' $ find (\x -> fst x == ident) xs -- has to be there + fresh <- freshen targIdent + let initialRecDict = M.singleton targIdent (fresh,ty,targExpr) + dict <- collectRecBinds ty initialRecDict targExpr + let renameMap = (\(i,t,_) -> (i,t)) <$> dict + bindingMap = M.elems dict + binds <- traverse (\(newId,newTy,oldE) -> makeBind renameMap newId newTy oldE) bindingMap + case M.lookup targIdent renameMap of + Just (newId,newTy) -> do + let body = pure (FVar newTy $ qualifyNull newId) + pure $ gLet binds body + Nothing -> throwError + $ MonoError + $ "Couldn't inline " <> showIdent' ident <> " - identifier didn't appear in collected bindings:\n " <> show renameMap + -- TODO: This is a temporary hack to get builtins working w/o a real linker. + else throwError $ MonoError "Imports aren't supported yet!" + wrong@(Qualified (BySourcePos _) _) -> + throwError + $ MonoError + $ "Cannot inline variable qualified by SourcePos. Such a variable should be bound (and ergo not exist at this stage of compilation)" + <> "\n Variable: " + <> show wrong + where + {- Arguments: + 1. A renaming dictionary, + 2. An Identifier which represents the new name of a binding (and should be present in the renaming dictionary), + 3. The new, possibly monomorphic (hopefully more-monomorphic at least) type which will be forcibly assigned to the body expression), + 4. A (possibly polymorphic) expression that will become the decl body + + Constructs a BindE where the Ident is the 2nd arg and the body is + the 4th arg forcibly assigned the type of the 3rd arg. + -} + makeBind :: Map Ident (Ident,SourceType) -- Map OldName (NewName,TypeToAssign) + -> Ident -- NewName + -> SourceType -- TypeToAssign + -> Exp WithObjects PurusType (FVar PurusType) -- Declaration body + -> Monomorphizer (BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)) + makeBind renameDict newIdent t e = trace ("makeBind: " <> showIdent' newIdent) $ do + e' <- updateFreeVars renameDict <$> monomorphizeWithType t e + pure $ NonRecursive newIdent e' + + -- Find a declaration body in the *module* scope + findDeclarationBody :: Ident -> Monomorphizer (Maybe (Exp WithObjects PurusType (FVar PurusType))) + findDeclarationBody nm = go <$> getModBinds + where + go :: [BindE PurusType (Exp WithObjects PurusType) (FVar PurusType)] + -> Maybe (Exp WithObjects PurusType (FVar PurusType)) + go [] = Nothing + go (b:bs) = case b of + NonRecursive nm' e -> if nm' == nm then Just e else go bs + Recursive xs -> case find (\x -> fst x == nm) xs of + Nothing -> go bs + Just (_,e) -> Just e + + {- RECURSIVE BINDINGS + + First, we need to walk the target expression and collect a list of all of the used + bindings and the type that they must be when monomorphized, and the new identifier for their + monomorphized/instantiated version. (We *don't* change anything here) + + Each of these `collectX` functions is specialized tool for collecting used bindings and + deducing the type to which they should be assigned (based, initially, on the SourceType + argument to `inlineAs`) + -} + + -- Top-level collection function + collectRecBinds :: + PurusType -> + Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType)) -> + Exp WithObjects PurusType (FVar PurusType) -> + Monomorphizer (Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType))) + collectRecBinds t visited e = trace ("collectRecBinds:\n " <> ppExp e <> "\n " <> prettyTypeStr t) $ case e of + LitE _ (ArrayL arr) -> trace "crbARRAYLIT" $ case t of + ArrayT inner -> do + innerBinds <- foldM (collectRecBinds inner) visited arr + pure $ visited <> innerBinds + _ -> throwError $ MonoError ("Failed to collect recursive binds: " <> prettyTypeStr t <> " is not an Array type") + LitE _ (ObjectL _ fs) -> trace "crbOBJLIT" $ case t of + RecordT fields -> do + let fieldMap = mkFieldMap fields + innerBinds <- collectRecFieldBinds visited fieldMap fs + pure $ visited <> innerBinds + _ -> throwError $ MonoError ("Failed to collect recursive binds: " <> prettyTypeStr t <> " is not a Record type") + LitE _ _ -> trace "crbLIT" $ pure visited + CtorE _ _ _ _ -> trace "crbCTOR" $ pure visited + ObjectUpdateE _ _ _ _ updateFields -> trace "crbOBJUPDATE" $ case t of + RecordT fields -> do + let fieldMap = mkFieldMap fields + innerBinds <- collectRecFieldBinds visited fieldMap updateFields + pure $ visited <> innerBinds + _ -> throwError $ MonoError ("Failed to collect recursive binds: " <> prettyTypeStr t <> " is not a Record type") + AccessorE _ _ _ _ -> trace "crbACCSR" $ pure visited -- idk. given (x.a :: t) we can't say what x is. + absE@(LamE _ _ _) -> trace ("crbABS TOARGS: " <> prettyTypeStr t) $ collectFun visited absE (splitFunTyParts t) + app@(AppE _ e2) -> trace "crbAPP" $ do + let (f,args) = unsafeAnalyzeApp app + types = (expTy F <$> args) <> [t] + funBinds' <- collectFun visited f types + let funBinds = visited <> funBinds' + argBinds <- collectRecBinds (head types) funBinds e2 + pure $ funBinds <> argBinds + V ((FVar _ (Qualified (ByModuleName _) nm))) -> trace ("crbVAR: " <> showIdent' nm) $ case M.lookup nm visited of + Nothing -> findDeclarationBody nm >>= \case + Nothing -> throwError $ MonoError $ "No declaration correponding to name " <> showIdent' nm <> " found in the module" + Just ex -> do + freshNm <- freshen nm + let this = (freshNm,t,ex) + pure $ M.insert nm this visited + Just _ -> pure visited -- might not be right, might need to check that the types are equal? ugh keeping track of scope is a nightmare + V ((FVar _ (Qualified _ nm))) -> trace ("crbVAR_: " <> showIdent' nm) $ pure visited + CaseE _ _ alts -> trace "crbCASE" $ do + let flatAlts = concatMap extractAndFlattenAlts alts + foldMScopeViaExp visited (collectRecBinds t) flatAlts + LetE _ _ ex -> case transverseScopeViaExp' (\expr' -> collectRecBinds t visited expr') ex of + B _ -> pure visited + F act -> act + + -- Collect from the fields of an object + collectRecFieldBinds :: Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType)) + -> M.Map PSString (RowListItem SourceAnn) + -> [(PSString, Exp WithObjects PurusType (FVar PurusType))] + -> Monomorphizer (Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType))) + collectRecFieldBinds visited _ [] = pure visited + collectRecFieldBinds visited cxt ((lbl,e):rest) = trace "collectRecFieldBinds" $ do + RowListItem{..} <- note ("No type for field with label " <> T.unpack (prettyPrintString lbl) <> " when collecting record binds") + $ M.lookup lbl cxt + this <- collectRecBinds rowListType visited e + collectRecFieldBinds (visited <> this) cxt rest + + -- Collect from a function expression + collectFun :: Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType)) + -> Exp WithObjects PurusType (FVar PurusType) + -> [SourceType] + -> Monomorphizer (Map Ident (Ident, SourceType, Exp WithObjects PurusType (FVar PurusType))) + collectFun visited e [t] = trace ("collectFun FIN:\n " <> {- -ppExp e <> " :: " -} prettyTypeStr t) $ do + rest <- collectRecBinds t visited e + pure $ visited <> rest + collectFun visited e (t:ts) = + trace ("collectFun:\n " <> ppExp e <> "\n " <> prettyTypeStr t <> "\n" <> show ts) $ + case e of + LamE (ForAll{}) bv body'' -> do + let body' = updateVarTyS bv t body'' + transversed = transverseScopeViaExp' (\expr' -> collectFun visited expr' ts) body' + case transversed of + -- NOTE/REVIEW: idk what to do w/ a bound var here. Nothing seems like it might be right? + B _ -> pure visited + F act -> act + + (V ((FVar _ (Qualified (ByModuleName _) nm)))) -> trace ("collectFun VAR: " <> showIdent' nm) $ do + case M.lookup nm visited of + Nothing -> do + let t' = foldr1 function (t:ts) + msg = "Couldn't find a declaration with identifier " <> showIdent' nm <> " to inline as " <> prettyTypeStr t + declBody <- note msg =<< findDeclarationBody nm + freshNm <- freshen nm + let visited' = M.insert nm (freshNm,t',declBody) visited + collectRecBinds t' visited' declBody + Just _ -> pure visited + + other -> throwError $ MonoError $ "Unexpected expression in collectFun:\n " <> ppExp other + collectFun _ _ [] = throwError $ MonoError "Ran out of types in collectFun" + + + +{- | "Forcibly" assigns the provided type to the provided expression. + Works recursively, so that all of the types of all sub-expressions are + also forcibly assigned so as to conform with the provided type. + + E.g. `monomorphizeWithType (Int -> Int) (\(x :: a) -> (f :: a -> Int) x)` + should yield `(\(x :: Int) -> (f :: Int -> Int) x)` + + This is used during inlining. At the point where we attempt to inline a + polymorphic function, we should know which types the type variables + ought to be instantiated to (if it can be known). +-} +monomorphizeWithType :: + PurusType -> + Exp WithObjects PurusType (FVar PurusType) -> + Monomorphizer (Exp WithObjects PurusType (FVar PurusType)) +monomorphizeWithType ty expr + | expTy F expr == ty = pure expr + | otherwise = trace ("monomorphizeWithType:\n " <> ppExp expr <> "\n " <> prettyTypeStr ty) $ case expr of + LitE ty' (ArrayL arr) -> case ty' of + ArrayT inner -> LitE ty . ArrayL <$> traverse (monomorphizeWithType inner) arr + _ -> throwError $ MonoError ("Failed to collect recursive binds: " <> prettyTypeStr ty <> " is not a Record type") + + LitE _ (ObjectL ext fs) -> case ty of + RecordT fields -> do + let fieldMap = mkFieldMap fields + LitE ty . ObjectL ext <$> monomorphizeFieldsWithTypes fieldMap fs + _ -> throwError $ MonoError ("Failed to collect recursive binds: " <> prettyTypeStr ty <> " is not a Record type") + + LitE _ lit -> pure $ LitE ty lit + + CtorE _ tName cName fs -> pure $ CtorE ty tName cName fs + + ObjectUpdateE ext _ orig copyFields updateFields -> case ty of + RecordT fields -> do + let fieldMap = mkFieldMap fields + -- idk. do we need to do something to the original expression or is this always sufficient? + updateFields' <- monomorphizeFieldsWithTypes fieldMap updateFields + pure $ ObjectUpdateE ext ty orig copyFields updateFields' + _ -> throwError $ MonoError ("Failed to collect recursive binds: " <> prettyTypeStr ty <> " is not a Record type") + + AccessorE ext _ str e -> pure $ AccessorE ext ty str e -- idk? + + fun@(LamE _ bv body) -> trace ("MTABs:\n " <> ppExp fun <> " :: " <> prettyTypeStr ty) $ do + case ty of + (a :-> b) -> do + -- REVIEW: If something is weirdly broken w/ bound vars look here first + freshBV <- freshBVar a + let replaceBVar = mapBound $ \x -> if x == bv then freshBV else x + body' = replaceBVar $ updateVarTyS bv a body + body'' <- transverseScopeViaExp (monomorphizeWithType b) body' + pure $ LamE ty freshBV body'' + _ -> throwError $ MonoError "Abs isn't a function" + + app@(AppE _ e2) -> trace ("MTAPP:\n " <> ppExp app) $ do + let (f,args) = unsafeAnalyzeApp app + e1' <- handleFunction f args + pure $ AppE e1' e2 + + V a -> pure $ V a -- idk + + CaseE _ scrut alts -> do + let f = monomorphizeWithType ty + goAlt :: Alt WithObjects PurusType (Exp WithObjects PurusType) (FVar PurusType) + -> Monomorphizer (Alt WithObjects PurusType (Exp WithObjects PurusType) (FVar PurusType)) + goAlt (UnguardedAlt bindings binders result) = + UnguardedAlt bindings binders <$> transverseScopeViaExp f result + CaseE ty scrut <$> traverse goAlt alts + + LetE a binds e -> LetE a binds <$> transverseScopeViaExp (monomorphizeWithType ty) e + where + monomorphizeFieldsWithTypes :: M.Map PSString (RowListItem SourceAnn) -> [(PSString, Exp WithObjects PurusType (FVar PurusType))] -> Monomorphizer [(PSString, Exp WithObjects PurusType (FVar PurusType))] + monomorphizeFieldsWithTypes _ [] = pure [] + monomorphizeFieldsWithTypes cxt ((lbl,e):rest) = do + RowListItem{..} <- note ("No type for field with label " <> T.unpack (prettyPrintString lbl) <> " when monomorphizing record") + $ M.lookup lbl cxt + rest' <- monomorphizeFieldsWithTypes cxt rest + e' <- monomorphizeWithType rowListType e + pure $ (lbl,e') : rest' diff --git a/src/Language/PureScript/CoreFn/Convert/ToPIR.hs b/src/Language/PureScript/CoreFn/Convert/ToPIR.hs new file mode 100644 index 000000000..c3425fc4b --- /dev/null +++ b/src/Language/PureScript/CoreFn/Convert/ToPIR.hs @@ -0,0 +1,414 @@ +{-# OPTIONS_GHC -Wno-orphans #-} -- has to be here (more or less) +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE DeriveTraversable, DeriveAnyClass #-} +{-# LANGUAGE InstanceSigs #-} +{-# LANGUAGE StandaloneDeriving #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE PartialTypeSignatures #-} + +module Language.PureScript.CoreFn.Convert.ToPIR where +{- turning this module off for now to test the monomorphizer rewrite +import Prelude +import Language.PureScript.Names (Qualified (..), ProperName(..), runIdent, pattern ByThisModuleName, disqualify) +import Language.PureScript.CoreFn.FromJSON () +import Data.Text qualified as T +import Language.PureScript.PSString (prettyPrintString) +import Data.Text (Text) +import Bound +import Control.Monad +import Data.Bifunctor (Bifunctor(first)) +import Data.List.NonEmpty qualified as NE +import Language.PureScript.Constants.Prim qualified as C +import Data.Map (Map) + -- mainly for the module (we might need it for constructors? idk) +import Language.PureScript.CoreFn.Convert.IR +import PlutusIR +import PlutusIR qualified as PIR +import PlutusCore.Default +import Control.Monad.State +import PlutusCore (Unique (..), getDefTypeCheckConfig) +import Language.PureScript.Constants.PLC +import Data.Map qualified as M +import Language.PureScript.CoreFn.Desugar.Utils (showIdent') +import PlutusIR.MkPir hiding (error) +import qualified Language.PureScript.CoreFn.Convert.IR as IR +import Language.PureScript.CoreFn.Convert.DesugarObjects +import Bound.Scope (instantiateEither) +import Language.PureScript.Constants.Purus qualified as C +import PlutusIR.Core.Instance.Pretty.Readable (prettyPirReadable) +import PlutusIR.Compiler ( compileToReadable, Compiling, toDefaultCompilationCtx, CompilationCtx, compileProgram ) +import PlutusCore.Version +import PlutusIR.Compiler.Provenance +import PlutusCore.Quote +import Control.Monad.Trans.Except (ExceptT, runExceptT) +import PlutusIR.Error +import Control.Monad.Reader +import PlutusCore qualified as PLC +import Control.Exception +import Data.List (sortOn) +import Control.Lens ((&),(.~),ix) +import PlutusCore.Evaluation.Machine.Ck +import PlutusCore.Evaluation.Machine.ExBudgetingDefaults qualified as PLC +import Test.Tasty +import Test.Tasty.HUnit + +type PLCProgram uni fun a = PLC.Program PLC.TyName PLC.Name uni fun (Provenance a) + +fuckThisMonadStack :: + forall e m c b. + (e ~ Error DefaultUni DefaultFun (Provenance ()) + , c ~ CompilationCtx DefaultUni DefaultFun () + , m ~ ExceptT e (ExceptT e (QuoteT (Reader c))) + ) + => (Compiling m e DefaultUni DefaultFun ()) => m b -> Either String b +fuckThisMonadStack x = + let + res :: Either e b + res = do + plcConfig <- getDefTypeCheckConfig (Original ()) + let ctx = toDefaultCompilationCtx plcConfig + join $ flip runReader ctx $ runQuoteT $ runExceptT $ runExceptT x + in first show res + +runPLCProgram :: PLCProgram DefaultUni DefaultFun () -> (EvaluationResult (PLC.Term TyName Name DefaultUni DefaultFun ()),[Text]) +runPLCProgram (PLC.Program _ _ c) = unsafeEvaluateCk PLC.defaultBuiltinsRuntime $ void c + +runPLCProgramTest :: String + -> (EvaluationResult (PLC.Term TyName Name DefaultUni DefaultFun ()),[Text]) + -> FilePath + -> Text + -> TestTree +runPLCProgramTest testName expected path decl = testCase testName $ do + prog <- declToUPLC path decl + let out = runPLCProgram prog + assertEqual "program output matches expected " expected out + +declToUPLC :: FilePath + -> Text + -> IO (PLCProgram DefaultUni DefaultFun ()) +declToUPLC path decl = prepPIR path decl >>= \case + (mainExpr,dict) -> do + tcMap <- rethrowIO $ mkTyConMap dict + ctorMap <- rethrowIO $ mkConstructorMap dict + let initialState = ConvertState 0 M.empty M.empty tcMap ctorMap + result = evalState (toPIR F mainExpr) initialState + putStrLn $ replicate 20 '-' <> "PIR" <> replicate 20 '-' + print $ prettyPirReadable result + putStrLn $ replicate 43 '-' <> "\n" + let input = Program (Original ()) latestVersion (Original <$> result) + readable <- aghhhh . fuckThisMonadStack $ compileToReadable input + aghhhh . fuckThisMonadStack $ compileProgram (void readable) + + where + aghhhh = either (throwIO . userError) pure + rethrowIO = \case + Left te@(TypeConvertError _ _ _ ) -> error (prettyErrorT te) + Right x -> pure x + +data PIRConvertError = PIRConvertError String -- TODO: Refine later + +type PIRTerm = Term TyName Name DefaultUni DefaultFun () + +type PIRType = Type TyName DefaultUni () + +type PIRBindings = Binding TyName Name DefaultUni DefaultFun () + +{- SOP (just so i have an easy reference example) + +data Maybe a = Just a | Nothing + +type Maybe a = [[a],[]] + +-} + +mkTyName :: Text -> State ConvertState TyName +mkTyName t = do + tvMap <- gets tyVarMap + case M.lookup t tvMap of + Nothing -> do + i <- getCounter + let nm = TyName $ Name t (Unique i) + modify $ \(ConvertState ix tvs vs tcd ctd) -> ConvertState ix (M.insert t i tvs) vs tcd ctd + pure nm + Just i -> pure $ TyName $ Name t (Unique i) + +mkTermName :: Text -> State ConvertState Name +mkTermName t = do + tvMap <- gets varMap + case M.lookup t tvMap of + Nothing -> do + i <- getCounter + let nm = Name t (Unique i) + modify $ \(ConvertState ix tvs vs tcd ctd) -> ConvertState ix tvs (M.insert t i vs) tcd ctd + pure nm + Just i -> pure $ Name t (Unique i) + +getCounter :: State ConvertState Int +getCounter = do + i <- gets counter + modify' $ \(ConvertState _ tvs vs tcd ctd) -> ConvertState (i + 1) tvs vs tcd ctd + pure i + +genFreshName :: State ConvertState Name +genFreshName = do + i <- getCounter + pure $ Name ("~" <> T.pack (show i)) (Unique i) + +genFreshTyName :: State ConvertState TyName +genFreshTyName = TyName <$> genFreshName + +-- N.B. We use the counter for type names (b/c we don't have Bound ADT) +data ConvertState = ConvertState { + counter :: Int, + tyVarMap :: Map Text Int, + varMap :: Map Text Int, + tyConDict :: TyConDict, + ctorDict :: CtorDict + } + +-- To avoid capturing quantified type variables in different scopes +locally :: State ConvertState a -> State ConvertState a +locally m = do + s <- get + let (a,ConvertState{..}) = runState m s + modify' $ \cs -> cs {counter = counter} + pure a + +-- REVIEW/TODO/FIXME: We need to ensure that type variables are also well scoped and unique. +-- Or at least I think we do? It's hard to tell whether that can still be +-- a problem after monomorphization. +toPIRType :: Ty -> State ConvertState PIRType +toPIRType = \case + IR.TyVar txt -> do + tyName <- mkTyName txt + pure $ PIR.TyVar () tyName + TyCon qtn@(Qualified qb tn) -> case qb of + ByThisModuleName "Builtin" -> pure $ handleBuiltinTy qtn + ByThisModuleName "Prim" -> pure $ handlePrimTy qtn + -- ByThisModuleName "$GEN" -> handleGenTuple tn don't think we need this b/c magic tuples? + _ -> gets tyConDict >>= \tcDict -> case lookupSOP tn tcDict of + Nothing -> error $ "TyCon not found in context " <> T.unpack (runProperName tn) + Just sop -> do + let strippedIndices :: [[Ty]] + strippedIndices = snd <$> sop + PIR.TySOP () <$> (traverse . traverse) toPIRType strippedIndices + -- TODO: Special handling for function types (-> is a TyCon in PS but a Ctor of the Type ADT in plc ) + IR.TyApp t1 t2 -> goTypeApp t1 t2 + Forall _ v mbk ty _ -> do + let k = mkKind mbk + tyName <- mkTyName v + ty' <- toPIRType ty + pure $ TyForall () tyName k ty' + other -> error $ "Upon reflection, other types like " <> ppTy other <> " shouldn't be allowed in the Ty ast" + where + goTypeApp (IR.TyApp f a) b + | f == TyCon C.Function = do + a' <- toPIRType a + b' <- toPIRType b + pure $ PIR.TyFun () a' b' + + handleBuiltinTy = \case + C.BuiltinData -> TyBuiltin () (SomeTypeIn DefaultUniData) + C.BuiltinPair -> TyBuiltin () (SomeTypeIn DefaultUniProtoPair) + C.BuiltinList -> TyBuiltin () (SomeTypeIn DefaultUniProtoList) + C.BuiltinByteString -> TyBuiltin () (SomeTypeIn DefaultUniByteString) + other -> error $ "error: unsupported builtin type: " <> show other + + handlePrimTy = \case + C.Function -> error "function types should be caught in apps" + C.Array -> TyBuiltin () (SomeTypeIn DefaultUniProtoList) -- is this wrong? do we want a SOP list? too tired to know + C.String -> TyBuiltin () (SomeTypeIn DefaultUniString) + C.Char -> TyBuiltin () (SomeTypeIn DefaultUniInteger) + C.Int -> TyBuiltin () (SomeTypeIn DefaultUniInteger) + C.Boolean -> TyBuiltin () (SomeTypeIn DefaultUniBool) + other -> error $ "unsupported prim tycon: " <> show other + + + -- TODO: Actually I should catch non- */*->Kind kinds way earlier than this and enforce that in the structure of Ty +mkKind :: Maybe IR.Ty -> PIR.Kind () +mkKind Nothing = error "not a type" +mkKind (Just t) = foldr1 (PIR.KindArrow ()) (collect t) + where + collect :: IR.Ty -> [PIR.Kind ()] + collect = \case + IR.TyCon C.Type -> [PIR.Type ()] + IR.TyCon C.Type :~> b -> PIR.Type () : collect b + other -> error $ "Not a thing of kind type " <> ppTy other + +-- TODO: Real monad stack w/ errors and shit +toPIR :: forall a. (a -> Var (BVar Ty) (FVar Ty)) -> Exp WithoutObjects Ty a -> State ConvertState PIRTerm +toPIR f = \case + V (f -> F (FVar _ ident)) -> do + let nm = showIdent' ident + case M.lookup (showIdent' ident) defaultFunMap of + Just aBuiltin -> pure $ Builtin () aBuiltin + Nothing -> do error $ showIdent' ident <> " isn't a builtin, and it shouldn't be possible to have a free variable that's anything but a builtin" + V (f -> B (BVar n t i)) -> PIR.Var () <$> mkTermName (runIdent i) + LitE _ lit -> litToPIR f lit + CtorE ty _ cn _ -> gets ctorDict >>= \dict -> do + case M.lookup cn dict of + Nothing -> error $ "Unknown Constructor " <> T.unpack (runProperName cn) + Just (_,ctorIx,_) -> locally $ do + -- TODO: We need to "walk under" quantifiers here a la `instantiatePolyType` from the CoreFn conversion + ctorFunTy <- NE.toList . splitFunTyParts <$> toPIRType ty + mkConstructorFun [] ctorIx ctorFunTy + LamE ty (BVar i vTy ident) body -> do + ty' <- toPIRType (argTy ty) + nm <- mkTermName (runIdent ident) + let iBody = instantiateEither (either (IR.V . B) (IR.V . F)) body + body' <- toPIR (>>= f) iBody + pure $ PIR.LamAbs () nm ty' body' + AppE e1 e2 -> do + e1' <- toPIR f e1 + e2' <- toPIR f e2 + pure $ PIR.Apply () e1' e2' + {- Too fucking complicated to do multiple scrutinee cases, will do later. + + I'm so beat so idk how great of a plan this is, but I'm gonna try to: + + - a) Transform the alts and the scrutinne into an expression :: scrutinee -> e' in Case _ ty e' [altBodies] using the binders + - b) Transform each alt body into a lambda. Somehow. + - c) Apply a to b. Hopefully! + -} + CaseE ty [scrutinee] alts -> do + scrutinee' <- toPIR f scrutinee + assembleScrutinee scrutinee' ty alts + -- TODO: I'm just going to mark all binding groups as recursive for now and do + -- the sophisticated thing later. so tired. + LetE cxtmap binds exp -> do + let flatBinds = concatMap flattenBind binds + named <- traverse (\(i,e) -> (,e) <$> mkTermName (runIdent i)) flatBinds + -- REVIEW: should they all be strict? + bindings <- traverse mkBinding named + case NE.nonEmpty bindings of + Just bindings' -> do + exp' <- toPIR (>>= f) $ instantiateEither (either (IR.V . B) (IR.V . F)) exp + pure $ PIR.Let () PIR.Rec bindings' exp' + Nothing -> error "non empty bindings" + where + mkBinding :: (Name, Scope (BVar Ty) (Exp WithoutObjects Ty) a) -> State ConvertState (Binding TyName Name DefaultUni DefaultFun ()) + mkBinding (nm,scopedExp) = do + let ty = eTy' f scopedExp + ty' <- toPIRType ty + exp' <- toPIR (>>= f) $ instantiateEither (either (IR.V . B) (IR.V . F)) scopedExp + pure $ TermBind () Strict (VarDecl () nm ty') exp' + + assembleScrutinee :: PIRTerm -> Ty -> [Alt WithoutObjects Ty (Exp WithoutObjects Ty) a] -> State ConvertState (Term TyName Name DefaultUni DefaultFun ()) + assembleScrutinee scrut tx alts = do + let _binders = IR.getPat <$> alts + alted <- unzip <$> traverse (locally . goAlt tx) alts + let sopSchema = head . fst $ alted + ctorNumberedBranches = snd alted + failBranches <- traverse mkFailBranch sopSchema + tx' <- toPIRType tx + let resolvedBranches = foldr (\(i,x) acc -> acc & ix i .~ x) failBranches ctorNumberedBranches + pure $ Case () tx' scrut resolvedBranches + where + boolT = TyBuiltin () (SomeTypeIn DefaultUniBool) + mkFailBranch :: [Ty] -> State ConvertState PIRTerm + mkFailBranch [] = pure $ mkConstant () False + mkFailBranch [t] = do + lamName <- genFreshName + t' <- toPIRType t + pure $ PIR.LamAbs () lamName (PIR.TyFun () t' boolT) (mkConstant () False) + mkFailBranch (t:ts) = do + lamName <- genFreshName + t' <- toPIRType t + rest <- mkFailBranch ts + pure $ PIR.LamAbs () lamName (PIR.TyFun () t' boolT) rest + + goAlt :: Ty -> Alt WithoutObjects Ty (Exp WithoutObjects Ty) a -> State ConvertState ([[Ty]],(Int,PIRTerm)) + goAlt t (UnguardedAlt _ [pat] body) = do + body' <- toPIR (>>= f) $ instantiateEither (either (IR.V . B) (IR.V . F)) body + patToBoolFunc body' t pat + where + + patToBoolFunc :: PIRTerm -> Ty -> Pat WithoutObjects (Exp WithoutObjects Ty) a -> State ConvertState ([[Ty]],(Int,PIRTerm)) + patToBoolFunc res tx = \case + ConP tn cn ips -> do + ctordict <- gets ctorDict + tcdict <- gets tyConDict + tx' <- toPIRType tx + let cn' = disqualify cn + tn' = disqualify tn + case (M.lookup cn' ctordict, M.lookup tn' tcdict) of + (Just (_,ctorix,tys), Just (_,_,ctors)) -> do + let ctorTypes = map snd . sortOn fst $ ctors + ibfs <- goCtorArgs (zip tys ips) + pure (ctorTypes,(ctorix,ibfs)) + where + goCtorArgs :: [(Ty,Pat WithoutObjects (Exp WithoutObjects Ty) a)] -> State ConvertState PIRTerm + goCtorArgs [] = pure res + goCtorArgs [(t,VarP nm)] = do + nm' <- mkTermName (runIdent nm) + t' <- toPIRType t + pure $ LamAbs () nm' t' res + goCtorArgs ((t,VarP nm):rest) = do + nm' <- mkTermName (runIdent nm) + t' <- toPIRType t + rest' <- goCtorArgs rest + pure $ LamAbs () nm' t' rest' + + -- NOTE: We don't have force/delay in PIR so I think we have to use type abstraction/instantiation + -- force ((\cond -> IfThenElse cond (delay caseT) (delay caseF)) cond) + -- TyInst _ + -- This is probably wrong and we need quantifiers (see https://github.com/IntersectMBO/plutus/blob/381172295c0b0a8f17450b8377ee5905f03d294b/plutus-core/plutus-ir/src/PlutusIR/Transform/NonStrict.hs#L82-L95) + -- TyInst ann (Var ann name) (TyForall ann a (Type ann) (TyVar ann a)) + -- TermBind x Strict (VarDecl x' name (TyForall ann a (Type ann) ty)) (TyAbs ann a (Type ann) rhs) + pIfTe :: PIRTerm -> PIRTerm -> PIRTerm -> State ConvertState PIRTerm + pIfTe cond troo fawlse = do + scrutineeNm <- genFreshName + let scrutineeTNm = TyName scrutineeNm + let boolT = TyBuiltin () (SomeTypeIn DefaultUniBool) + builtinIfTe = Builtin () IfThenElse + ifte c t f = PIR.Apply () (PIR.Apply () (PIR.Apply () builtinIfTe c) t) f + sVar = (PIR.Var () scrutineeNm) + tBranch = (PIR.TyAbs () scrutineeTNm (PIR.Type ()) troo) + fBranch = (PIR.TyAbs () scrutineeTNm (PIR.Type ()) fawlse) + body = PIR.LamAbs () scrutineeNm boolT + $ ifte sVar tBranch fBranch + forced = TyInst () body (TyForall () scrutineeTNm (PIR.Type ()) (PIR.TyVar () scrutineeTNm)) + pure $ PIR.Apply () forced cond + + +argTy :: Ty -> Ty +argTy (a :~> b) = a +argTy other = other + +mkConstructorFun :: [Name] -> Int -> [PIRType] -> State ConvertState PIRTerm +mkConstructorFun acc ctorIx [ty] = do + let argsInOrder = reverse acc + ctorIx' = fromIntegral ctorIx + pure $ PIR.Constr () ty ctorIx' (PIR.Var () <$> argsInOrder) +mkConstructorFun acc cix (t:ts) = do + newName <- genFreshName + -- \/ NOTE: Not sure if abstractions here have the type of the bound var or the type of the abstraction as a whole. + -- If not working look here first + let lamTy = foldr1 (TyFun ()) (t:ts) + rest <- mkConstructorFun (newName:acc) cix ts + pure $ LamAbs () newName lamTy rest +mkConstructorFun _ _ _ = error "mkConstructorFun failed - should be impossible" + +litToPIR :: forall a. (a -> Var (BVar Ty) (FVar Ty)) -> Lit WithoutObjects (Exp WithoutObjects Ty a) -> State ConvertState PIRTerm +litToPIR f = \case + IntL i -> pure $ mkConstant () i + NumL _ -> error "TODO: Doubles" + StringL str -> -- REVIEW/TODO/FIXME: This is *TOTALLY* wrong + pure . mkConstant () $ prettyPrintString str + CharL c -> -- REVIEW/TODO/FIXME: Is this what we want? + pure + . mkConstant () + . toInteger + . fromEnum + $ c + BoolL b -> pure $ mkConstant () b + ArrayL arr -> error $ "Too complicated for 5am, do tomorrow" + <> " Make sure to check for nested array lits (also check that everywhere else)" + +-- can't figure out if this is exported in w/e version of plutus-core we're on here +splitFunTyParts :: Type tyname uni a -> NE.NonEmpty (Type tyname uni a) +splitFunTyParts = \case + TyFun _ t1 t2 -> t1 NE.<| splitFunTyParts t2 + t -> pure t +-} diff --git a/src/Language/PureScript/CoreFn/Desugar.hs b/src/Language/PureScript/CoreFn/Desugar.hs index 34bf08f1f..ec58e3b89 100644 --- a/src/Language/PureScript/CoreFn/Desugar.hs +++ b/src/Language/PureScript/CoreFn/Desugar.hs @@ -1,272 +1,701 @@ -module Language.PureScript.CoreFn.Desugar (moduleToCoreFn) where +{- HLINT ignore "Use void" -} +{- HLINT ignore "Use <$" -} -import Prelude -import Protolude (ordNub, orEmpty) +module Language.PureScript.CoreFn.Desugar(moduleToCoreFn) where -import Control.Arrow (second) +import Prelude +import Protolude (ordNub, orEmpty, zipWithM, MonadError (..), sortOn, Bifunctor (bimap)) -import Data.Function (on) import Data.Maybe (mapMaybe) -import Data.Tuple (swap) import Data.List.NonEmpty qualified as NEL import Data.Map qualified as M import Language.PureScript.AST.Literals (Literal(..)) -import Language.PureScript.AST.SourcePos (pattern NullSourceSpan, SourceSpan(..)) -import Language.PureScript.AST.Traversals (everythingOnValues) -import Language.PureScript.Comments (Comment) +import Language.PureScript.AST.SourcePos (SourceSpan(..), SourceAnn) import Language.PureScript.CoreFn.Ann (Ann, ssAnn) import Language.PureScript.CoreFn.Binders (Binder(..)) import Language.PureScript.CoreFn.Expr (Bind(..), CaseAlternative(..), Expr(..), Guard) -import Language.PureScript.CoreFn.Meta (ConstructorType(..), Meta(..)) +import Language.PureScript.CoreFn.Utils (exprType, stripQuantifiers) +import Language.PureScript.CoreFn.Meta (Meta(..)) import Language.PureScript.CoreFn.Module (Module(..)) import Language.PureScript.Crash (internalError) -import Language.PureScript.Environment (DataDeclType(..), Environment(..), NameKind(..), isDictTypeName, lookupConstructor, lookupValue) +import Language.PureScript.Environment ( + pattern (:->), + pattern ArrayT, + DataDeclType(..), + Environment(..), + NameKind(..), + isDictTypeName, + lookupConstructor, + lookupValue, + NameVisibility (..), + tyBoolean, + tyFunction, + tyString, + tyChar, + tyInt, + tyNumber, + function, + pattern RecordT ) import Language.PureScript.Label (Label(..)) -import Language.PureScript.Names (pattern ByNullSourcePos, Ident(..), ModuleName, ProperName(..), ProperNameType(..), Qualified(..), QualifiedBy(..), getQual) +import Language.PureScript.Names ( + pattern ByNullSourcePos, Ident(..), + ModuleName, + ProperName(..), + Qualified(..), + QualifiedBy(..), + mkQualified, + runIdent, + coerceProperName, + Name (DctorName), ProperNameType (..), disqualify) import Language.PureScript.PSString (PSString) -import Language.PureScript.Types (pattern REmptyKinded, SourceType, Type(..)) -import Language.PureScript.AST qualified as A +import Language.PureScript.Types ( + pattern REmptyKinded, + SourceType, + Type(..), quantify, eqType, containsUnknowns, rowToList, RowListItem (..)) +import Language.PureScript.AST.Binders qualified as A +import Language.PureScript.AST.Declarations qualified as A +import Language.PureScript.AST.SourcePos qualified as A import Language.PureScript.Constants.Prim qualified as C +import Control.Monad.State.Strict (MonadState, gets, modify) +import Control.Monad.Writer.Class ( MonadWriter ) +import Language.PureScript.TypeChecker.Kinds ( kindOf ) +import Data.List.NonEmpty qualified as NE +import Control.Monad (forM, (>=>), foldM) +import Language.PureScript.Errors + ( MultipleErrors, errorMessage', SimpleErrorMessage(..)) +import Debug.Trace (traceM) +import Language.PureScript.CoreFn.Pretty ( ppType, renderExprStr ) +import Data.Text qualified as T +import Language.PureScript.Pretty.Values (renderValue) +import Language.PureScript.TypeChecker.Monad + ( bindLocalVariables, + bindNames, + getEnv, + makeBindingGroupVisible, + warnAndRethrowWithPositionTC, + withBindingGroupVisible, + CheckState(checkEnv, checkCurrentModule) ) +import Language.PureScript.CoreFn.Desugar.Utils + ( binderToCoreFn, + dedupeImports, + exportToCoreFn, + externToCoreFn, + findQualModules, + getConstructorMeta, + getLetMeta, + getModuleName, + getValueMeta, + importToCoreFn, + properToIdent, + purusTy, + reExportsToCoreFn, + showIdent', + ssA, + toReExportRef, + wrapTrace, + desugarConstraintTypes, + M, unwrapRecord, withInstantiatedFunType, desugarConstraintsInDecl, analyzeCtor, instantiate, ctorArgs, instantiatePolyType, lookupDictType, desugarCasesEverywhere + ) +import Text.Pretty.Simple (pShow) +import Data.Text.Lazy qualified as LT +import Data.Set qualified as S +import Data.Either (lefts) + +{- + CONVERSION MACHINERY + + NOTE: We run this *after* the initial typechecking/desugaring phase, using the Environment returned from that + initial pass. It's important to keep that in mind, for a few reasons: + - We know that everything is well-typed/scoped/properly renamed/desugared/etc. This assumption lets us safely do a bunch of things that wouldn't otherwise be safe. + - We have access to all of the type signatures for top-level declarations + - We have to fix the "lies" in the type signatures that emerge after desugaring, e.g. types w/ a class constraint represent values that take an additional dict argument + + NOTE: All of the "pure" conversion functions (i.e. which don't require the typechecker monad stack) are in Language.PureScript.CoreFn.Desugar.Utils. + This module is hard enough to understand, best to minimize its size. +-} -- | Desugars a module from AST to CoreFn representation. -moduleToCoreFn :: Environment -> A.Module -> Module Ann -moduleToCoreFn _ (A.Module _ _ _ _ Nothing) = +moduleToCoreFn :: forall m. M m => A.Module -> m (Module (Bind Ann) Ann) +moduleToCoreFn (A.Module _ _ _ _ Nothing) = internalError "Module exports were not elaborated before moduleToCoreFn" -moduleToCoreFn env (A.Module modSS coms mn decls (Just exps)) = - let imports = mapMaybe importToCoreFn decls ++ fmap (ssAnn modSS,) (findQualModules decls) - imports' = dedupeImports imports +moduleToCoreFn (A.Module modSS coms mn _decls (Just exps)) = do + setModuleName + desugarConstraintTypes + decls <- traverse desugarCasesEverywhere $ desugarConstraintsInDecl <$> _decls + let importHelper ds = fmap (ssAnn modSS,) (findQualModules ds) + imports = dedupeImports $ mapMaybe importToCoreFn decls ++ importHelper decls exps' = ordNub $ concatMap exportToCoreFn exps reExps = M.map ordNub $ M.unionsWith (++) (mapMaybe (fmap reExportsToCoreFn . toReExportRef) exps) externs = ordNub $ mapMaybe externToCoreFn decls - decls' = concatMap declToCoreFn decls - in Module modSS coms mn (spanName modSS) imports' exps' reExps externs decls' + decls' <- concat <$> traverse (declToCoreFn mn) decls + let dataDecls = mkDataDecls decls + pure $ Module modSS coms mn (spanName modSS) imports exps' reExps externs decls' dataDecls + where + setModuleName = modify $ \cs -> + cs {checkCurrentModule = Just mn} + +{- Turns out we need the data type declarations in order to reconstruct the SOP in PIR + + TODO/REVIEW/FIXME: This won't pull in data declarations from imports, we'll have to handle that in the linker. + +-} + +type DeclMapElem = (DataDeclType,[(T.Text, Maybe SourceType)], [A.DataConstructorDeclaration]) + +mkDataDecls :: [A.Declaration] -> M.Map (ProperName 'TypeName) DeclMapElem +mkDataDecls [] = M.empty +mkDataDecls (d:ds) = case go d of + Nothing -> mkDataDecls ds + Just kv -> uncurry M.insert kv $ mkDataDecls ds + where + go :: A.Declaration -> Maybe (ProperName 'TypeName,DeclMapElem) + go = \case + A.DataDeclaration _ ddTy nm args ctors -> Just (nm,(ddTy,args,ctors)) + _ -> Nothing + +{- | Given a SourcePos and Identifier, look up the type of that identifier, also returning its NameVisiblity. + + NOTE: Local variables should all be qualified by their SourcePos, whereas imports (and maybe top level decls in the module? can't remember) + are qualified by their ModuleName. What we do here is first look for a "local" type for the identifier using the provided source position, + then, if that fails, look up the identifier in the "global" scope using a module name. + + I *think* this is fine but I'm not *certain*. +-} +lookupType :: forall m. M m => A.SourcePos -> Ident -> m (SourceType,NameVisibility) +lookupType sp tn = do + mn <- getModuleName + env <- gets checkEnv + case M.lookup (Qualified (BySourcePos sp) tn) (names env) of + Nothing -> case M.lookup (mkQualified tn mn) (names env) of + Nothing -> error $ "No type found for " <> show tn + Just (ty,_,nv) -> do + traceM $ "lookupType: " <> showIdent' tn <> " :: " <> ppType 10 ty + pure (ty,nv) + Just (ty,_,nv) -> do + traceM $ "lookupType: " <> showIdent' tn <> " :: " <> ppType 10 ty + pure (ty,nv) + +getInnerArrayTy :: Type a -> Maybe (Type a) +getInnerArrayTy (ArrayT arr) = Just arr +getInnerArrayTy (ForAll _ _ _ _ ty _) = getInnerArrayTy ty +getInnerArrayTy _ = Nothing + +{-| Extracts inner type of an object if it is behind foralls +-} +getInnerObjectTy :: Type a -> Maybe (Type a) +getInnerObjectTy (RecordT row) = Just row +getInnerObjectTy (ForAll _ _ _ _ ty _) = getInnerObjectTy ty +getInnerObjectTy _ = Nothing + +objectToCoreFn :: forall m. M m => ModuleName -> SourceSpan -> SourceType -> SourceType -> [(PSString, A.Expr)] -> m (Expr Ann) +objectToCoreFn mn ss recTy row objFields = do + traceM $ "ObjLitTy: " <> show row + let (tyFields,_) = rowToList row + tyMap = M.fromList $ (\x -> (runLabel (rowListLabel x),x)) <$> tyFields + resolvedFields <- foldM (go tyMap) [] objFields + pure $ Literal (ss,[],Nothing) recTy (ObjectLiteral resolvedFields) + where + go :: M.Map PSString (RowListItem SourceAnn) -> [(PSString, Expr Ann)] -> (PSString, A.Expr) -> m [(PSString, Expr Ann)] + go tyMap acc (lbl,expr) = case M.lookup lbl tyMap of + Just rowListItem -> do + let fieldTy = rowListType rowListItem + expr' <- exprToCoreFn mn ss (Just fieldTy) expr + pure $ (lbl,expr'):acc + Nothing -> do -- error $ "row type missing field " <> T.unpack (prettyPrintString lbl) + expr' <- exprToCoreFn mn ss Nothing expr + pure $ (lbl,expr') : acc + +{- Converts declarations from their AST to CoreFn representation, deducing types when possible & inferring them when not possible. + + TODO: The module name can be retrieved from the monadic context and doesn't need to be passed around +-} + +-- newtype T = T Foo turns into T :: Foo -> Foo +declToCoreFn :: forall m. M m => ModuleName -> A.Declaration -> m [Bind Ann] +declToCoreFn _ (A.DataDeclaration (ss, com) Newtype name _ [ctor]) = wrapTrace ("decltoCoreFn NEWTYPE " <> show name) $ case A.dataCtorFields ctor of + [(_,wrappedTy)] -> do + -- traceM (show ctor) + let innerFunTy = quantify $ function wrappedTy wrappedTy + pure [NonRec (ss, [], declMeta) (properToIdent $ A.dataCtorName ctor) $ + Abs (ss, com, Just IsNewtype) innerFunTy (Ident "x") (Var (ssAnn ss) (purusTy wrappedTy) $ Qualified ByNullSourcePos (Ident "x"))] + _ -> error "Found newtype with multiple fields" where - -- Creates a map from a module name to the re-export references defined in - -- that module. - reExportsToCoreFn :: (ModuleName, A.DeclarationRef) -> M.Map ModuleName [Ident] - reExportsToCoreFn (mn', ref') = M.singleton mn' (exportToCoreFn ref') - - toReExportRef :: A.DeclarationRef -> Maybe (ModuleName, A.DeclarationRef) - toReExportRef (A.ReExportRef _ src ref) = - fmap - (, ref) - (A.exportSourceImportedFrom src) - toReExportRef _ = Nothing - - -- Remove duplicate imports - dedupeImports :: [(Ann, ModuleName)] -> [(Ann, ModuleName)] - dedupeImports = fmap swap . M.toList . M.fromListWith const . fmap swap - - ssA :: SourceSpan -> Ann - ssA ss = (ss, [], Nothing) - - -- Desugars member declarations from AST to CoreFn representation. - declToCoreFn :: A.Declaration -> [Bind Ann] - declToCoreFn (A.DataDeclaration (ss, com) Newtype _ _ [ctor]) = - [NonRec (ss, [], declMeta) (properToIdent $ A.dataCtorName ctor) $ - Abs (ss, com, Just IsNewtype) (Ident "x") (Var (ssAnn ss) $ Qualified ByNullSourcePos (Ident "x"))] - where - declMeta = isDictTypeName (A.dataCtorName ctor) `orEmpty` IsTypeClassConstructor - declToCoreFn d@(A.DataDeclaration _ Newtype _ _ _) = - error $ "Found newtype with multiple constructors: " ++ show d - declToCoreFn (A.DataDeclaration (ss, com) Data tyName _ ctors) = - flip fmap ctors $ \ctorDecl -> - let - ctor = A.dataCtorName ctorDecl - (_, _, _, fields) = lookupConstructor env (Qualified (ByModuleName mn) ctor) - in NonRec (ssA ss) (properToIdent ctor) $ Constructor (ss, com, Nothing) tyName ctor fields - declToCoreFn (A.DataBindingGroupDeclaration ds) = - concatMap declToCoreFn ds - declToCoreFn (A.ValueDecl (ss, com) name _ _ [A.MkUnguarded e]) = - [NonRec (ssA ss) name (exprToCoreFn ss com Nothing e)] - declToCoreFn (A.BindingGroupDeclaration ds) = - [Rec . NEL.toList $ fmap (\(((ss, com), name), _, e) -> ((ssA ss, name), exprToCoreFn ss com Nothing e)) ds] - declToCoreFn _ = [] - - -- Desugars expressions from AST to CoreFn representation. - exprToCoreFn :: SourceSpan -> [Comment] -> Maybe SourceType -> A.Expr -> Expr Ann - exprToCoreFn _ com _ (A.Literal ss lit) = - Literal (ss, com, Nothing) (fmap (exprToCoreFn ss com Nothing) lit) - exprToCoreFn ss com _ (A.Accessor name v) = - Accessor (ss, com, Nothing) name (exprToCoreFn ss [] Nothing v) - exprToCoreFn ss com ty (A.ObjectUpdate obj vs) = - ObjectUpdate (ss, com, Nothing) (exprToCoreFn ss [] Nothing obj) (ty >>= unchangedRecordFields (fmap fst vs)) $ fmap (second (exprToCoreFn ss [] Nothing)) vs - where - -- Return the unchanged labels of a closed record, or Nothing for other types or open records. - unchangedRecordFields :: [PSString] -> Type a -> Maybe [PSString] - unchangedRecordFields updated (TypeApp _ (TypeConstructor _ C.Record) row) = - collect row - where - collect :: Type a -> Maybe [PSString] - collect (REmptyKinded _ _) = Just [] - collect (RCons _ (Label l) _ r) = (if l `elem` updated then id else (l :)) <$> collect r - collect _ = Nothing - unchangedRecordFields _ _ = Nothing - exprToCoreFn ss com _ (A.Abs (A.VarBinder _ name) v) = - Abs (ss, com, Nothing) name (exprToCoreFn ss [] Nothing v) - exprToCoreFn _ _ _ (A.Abs _ _) = - internalError "Abs with Binder argument was not desugared before exprToCoreFn mn" - exprToCoreFn ss com _ (A.App v1 v2) = - App (ss, com, (isDictCtor v1 || isSynthetic v2) `orEmpty` IsSyntheticApp) v1' v2' - where - v1' = exprToCoreFn ss [] Nothing v1 - v2' = exprToCoreFn ss [] Nothing v2 - isDictCtor = \case - A.Constructor _ (Qualified _ name) -> isDictTypeName name - _ -> False - isSynthetic = \case - A.App v3 v4 -> isDictCtor v3 || isSynthetic v3 && isSynthetic v4 - A.Accessor _ v3 -> isSynthetic v3 - A.Var NullSourceSpan _ -> True - A.Unused{} -> True - _ -> False - exprToCoreFn ss com _ (A.Unused _) = - Var (ss, com, Nothing) C.I_undefined - exprToCoreFn _ com _ (A.Var ss ident) = - Var (ss, com, getValueMeta ident) ident - exprToCoreFn ss com _ (A.IfThenElse v1 v2 v3) = - Case (ss, com, Nothing) [exprToCoreFn ss [] Nothing v1] - [ CaseAlternative [LiteralBinder (ssAnn ss) $ BooleanLiteral True] - (Right $ exprToCoreFn ss [] Nothing v2) - , CaseAlternative [NullBinder (ssAnn ss)] - (Right $ exprToCoreFn ss [] Nothing v3) ] - exprToCoreFn _ com _ (A.Constructor ss name) = - Var (ss, com, Just $ getConstructorMeta name) $ fmap properToIdent name - exprToCoreFn ss com _ (A.Case vs alts) = - Case (ss, com, Nothing) (fmap (exprToCoreFn ss [] Nothing) vs) (fmap (altToCoreFn ss) alts) - exprToCoreFn ss com _ (A.TypedValue _ v ty) = - exprToCoreFn ss com (Just ty) v - exprToCoreFn ss com _ (A.Let w ds v) = - Let (ss, com, getLetMeta w) (concatMap declToCoreFn ds) (exprToCoreFn ss [] Nothing v) - exprToCoreFn _ com ty (A.PositionedValue ss com1 v) = - exprToCoreFn ss (com ++ com1) ty v - exprToCoreFn _ _ _ e = - error $ "Unexpected value in exprToCoreFn mn: " ++ show e - - -- Desugars case alternatives from AST to CoreFn representation. - altToCoreFn :: SourceSpan -> A.CaseAlternative -> CaseAlternative Ann - altToCoreFn ss (A.CaseAlternative bs vs) = CaseAlternative (map (binderToCoreFn ss []) bs) (go vs) - where - go :: [A.GuardedExpr] -> Either [(Guard Ann, Expr Ann)] (Expr Ann) - go [A.MkUnguarded e] - = Right (exprToCoreFn ss [] Nothing e) - go gs - = Left [ (exprToCoreFn ss [] Nothing cond, exprToCoreFn ss [] Nothing e) - | A.GuardedExpr g e <- gs - , let cond = guardToExpr g - ] - - guardToExpr [A.ConditionGuard cond] = cond - guardToExpr _ = internalError "Guard not correctly desugared" - - -- Desugars case binders from AST to CoreFn representation. - binderToCoreFn :: SourceSpan -> [Comment] -> A.Binder -> Binder Ann - binderToCoreFn _ com (A.LiteralBinder ss lit) = - LiteralBinder (ss, com, Nothing) (fmap (binderToCoreFn ss com) lit) - binderToCoreFn ss com A.NullBinder = - NullBinder (ss, com, Nothing) - binderToCoreFn _ com (A.VarBinder ss name) = - VarBinder (ss, com, Nothing) name - binderToCoreFn _ com (A.ConstructorBinder ss dctor@(Qualified mn' _) bs) = - let (_, tctor, _, _) = lookupConstructor env dctor - in ConstructorBinder (ss, com, Just $ getConstructorMeta dctor) (Qualified mn' tctor) dctor (fmap (binderToCoreFn ss []) bs) - binderToCoreFn _ com (A.NamedBinder ss name b) = - NamedBinder (ss, com, Nothing) name (binderToCoreFn ss [] b) - binderToCoreFn _ com (A.PositionedBinder ss com1 b) = - binderToCoreFn ss (com ++ com1) b - binderToCoreFn ss com (A.TypedBinder _ b) = - binderToCoreFn ss com b - binderToCoreFn _ _ A.OpBinder{} = - internalError "OpBinder should have been desugared before binderToCoreFn" - binderToCoreFn _ _ A.BinaryNoParensBinder{} = - internalError "BinaryNoParensBinder should have been desugared before binderToCoreFn" - binderToCoreFn _ _ A.ParensInBinder{} = - internalError "ParensInBinder should have been desugared before binderToCoreFn" - - -- Gets metadata for let bindings. - getLetMeta :: A.WhereProvenance -> Maybe Meta - getLetMeta A.FromWhere = Just IsWhere - getLetMeta A.FromLet = Nothing - - -- Gets metadata for values. - getValueMeta :: Qualified Ident -> Maybe Meta - getValueMeta name = - case lookupValue env name of - Just (_, External, _) -> Just IsForeign - _ -> Nothing - - -- Gets metadata for data constructors. - getConstructorMeta :: Qualified (ProperName 'ConstructorName) -> Meta - getConstructorMeta ctor = - case lookupConstructor env ctor of - (Newtype, _, _, _) -> IsNewtype - dc@(Data, _, _, fields) -> - let constructorType = if numConstructors (ctor, dc) == 1 then ProductType else SumType - in IsConstructor constructorType fields + declMeta = isDictTypeName (A.dataCtorName ctor) `orEmpty` IsTypeClassConstructor +-- Reject newtypes w/ multiple constructors +declToCoreFn _ d@(A.DataDeclaration _ Newtype _ _ _) = + error $ "Found newtype with multiple constructors: " ++ show d +-- Data declarations get turned into value declarations for the constructor(s) +declToCoreFn mn (A.DataDeclaration (ss, com) Data tyName _ ctors) = wrapTrace ("declToCoreFn DATADEC " <> T.unpack (runProperName tyName)) $ traverse go ctors + where + go ctorDecl = do + env <- gets checkEnv + let ctor = A.dataCtorName ctorDecl + (_, _, ctorTy, fields) = lookupConstructor env (Qualified (ByModuleName mn) ctor) + pure $ NonRec (ssA ss) (properToIdent ctor) $ Constructor (ss, com, Nothing) (purusTy ctorTy) tyName ctor fields +-- NOTE: This should be OK because you can data declarations can only appear at the top-level. +declToCoreFn mn (A.DataBindingGroupDeclaration ds) = wrapTrace "declToCoreFn DATA GROUP DECL" $ concat <$> traverse (declToCoreFn mn) ds +-- Essentially a wrapper over `exprToCoreFn`. Not 100% sure if binding the type of the declaration is necessary here? +-- NOTE: Should be impossible to have a guarded expr here, make it an error +declToCoreFn mn (A.ValueDecl (ss, _) name _ _ [A.MkUnguarded e]) = wrapTrace ("decltoCoreFn VALDEC " <> show name) $ do + traceM $ renderValue 100 e + (valDeclTy,nv) <- lookupType (spanStart ss) name + traceM (ppType 100 valDeclTy) + bindLocalVariables [(ss,name,valDeclTy,nv)] $ do + expr <- exprToCoreFn mn ss (Just valDeclTy) e -- maybe wrong? might need to bind something here? + pure [NonRec (ssA ss) name expr] +-- Recursive binding groups. This is tricky. Calling `typedOf` saves us a lot of work, but it's hard to tell whether that's 100% safe here +declToCoreFn mn (A.BindingGroupDeclaration ds) = wrapTrace "declToCoreFn BINDING GROUP" $ do + let typed = NE.toList $ extractTypeAndPrepareBind <$> ds + toBind = snd <$> typed + recBody <- bindLocalVariables toBind $ traverse goRecBindings typed + pure [Rec recBody] + where + -- If we only ever call this on a top-level binding group then this should be OK, all the exprs should be explicitly typed + extractTypeAndPrepareBind :: ((A.SourceAnn, Ident), NameKind, A.Expr) -> (A.Expr, (SourceSpan,Ident,SourceType,NameVisibility)) + extractTypeAndPrepareBind (((ss',_),ident),_,A.TypedValue _ e ty) = (e,(ss',ident,ty,Defined)) + extractTypeAndPrepareBind (((_,_),ident),_,_) = error $ "Top level declaration " <> showIdent' ident <> " should have a type annotation, but does not" + + goRecBindings :: (A.Expr, (SourceSpan,Ident,SourceType,NameVisibility)) -> m ((Ann, Ident), Expr Ann) + goRecBindings (expr,(ss',ident,ty,_)) = do + expr' <- exprToCoreFn mn ss' (Just ty) expr + pure ((ssA ss',ident), expr') +-- TODO: Avoid catchall case +declToCoreFn _ _ = pure [] + +-- Desugars expressions from AST to typed CoreFn representation. +exprToCoreFn :: forall m. M m => ModuleName -> SourceSpan -> Maybe SourceType -> A.Expr -> m (Expr Ann) +-- Array & Object literals can contain non-literal expressions. Both of these types should always be tagged +-- (i.e. returned as an AST.TypedValue) after the initial typechecking phase, so we expect the type to be passed in +exprToCoreFn mn ss (Just arrT) astlit@(A.Literal _ (ArrayLiteral ts)) + | Just ty <- getInnerArrayTy arrT + = wrapTrace ("exprToCoreFn ARRAYLIT " <> renderValue 100 astlit) $ do + traceM $ ppType 100 arrT + arr <- ArrayLiteral <$> traverse (exprToCoreFn mn ss (Just ty)) ts + pure $ Literal (ss,[],Nothing) arrT arr + +exprToCoreFn _ _ Nothing astlit@(A.Literal _ (ArrayLiteral _)) = + internalError $ "Error while desugaring Array Literal. No type provided for literal:\n" <> renderValue 100 astlit + +exprToCoreFn mn ss (Just recTy) (A.Literal _ (ObjectLiteral objFields)) + | Just row <- getInnerObjectTy recTy + = objectToCoreFn mn ss recTy row objFields + +exprToCoreFn _ _ (Just ty) (A.Literal _ (ObjectLiteral _)) = + internalError $ "Error while desugaring Object Literal. Unexpected type:\n" <> show ty + +exprToCoreFn _ _ Nothing astlit@(A.Literal _ (ObjectLiteral _)) = + internalError $ "Error while desugaring Object Literal. No type provided for literal:\n" <> renderValue 100 astlit + +-- Literals that aren't objects or arrays have deterministic types +exprToCoreFn _ _ _ (A.Literal ss (NumericLiteral (Left int))) = + pure $ Literal (ss,[],Nothing) tyInt (NumericLiteral (Left int)) +exprToCoreFn _ _ _ (A.Literal ss (NumericLiteral (Right number))) = + pure $ Literal (ss,[],Nothing) tyNumber (NumericLiteral (Right number)) +exprToCoreFn _ _ _ (A.Literal ss (CharLiteral char)) = + pure $ Literal (ss,[],Nothing) tyChar (CharLiteral char) +exprToCoreFn _ _ _ (A.Literal ss (BooleanLiteral boolean)) = + pure $ Literal (ss,[],Nothing) tyBoolean (BooleanLiteral boolean) +exprToCoreFn _ _ _ (A.Literal ss (StringLiteral string)) = + pure $ Literal (ss,[],Nothing) tyString (StringLiteral string) + +-- Accessor case is straightforward (these should always be typed explicitly) +exprToCoreFn mn ss (Just accT) accessor@(A.Accessor name v) = wrapTrace ("exprToCoreFn ACCESSOR " <> renderValue 100 accessor) $ do + v' <- exprToCoreFn mn ss Nothing v -- v should always have a type assigned during typechecking (i.e. it will be a TypedValue that will be unwrapped) + pure $ Accessor (ssA ss) accT name v' +exprToCoreFn mn ss Nothing accessor@(A.Accessor name v) = do + v' <- exprToCoreFn mn ss Nothing v + let vTy = exprType v' + env <- getEnv + case analyzeCtor vTy of + Nothing -> internalError $ "(1) Error while desugaring record accessor." + <> " No type provided for expression: \n" <> renderValue 100 accessor + <> "\nRecord type: " <> ppType 1000 vTy + <> "\nsynonyms: " <> show (runProperName . disqualify <$> M.keys env.types) + Just (TypeConstructor _ tyNm,_) -> case M.lookup (tyNameToCtorName tyNm) env.dataConstructors of + Nothing -> internalError $ "(2) Error while desugaring record accessor." + <> " No type provided for expression: \n" <> renderValue 100 accessor + Just (_,_,ty,_) -> case stripQuantifiers ty of + (_,RecordT inner :-> _) -> do + let tyMap = M.fromList $ (\x -> (runLabel (rowListLabel x),x)) <$> (fst $ rowToList inner) + case M.lookup name tyMap of + Just (rowListType -> resTy) -> pure $ Accessor (ssA ss) resTy name v' + Nothing -> internalError $ "(3) Error while desugaring record accessor." + <> " No type provided for expression: \n" <> renderValue 100 accessor + (_,other) -> internalError $ "****DEBUG:\n" <> ppType 100 other + where + tyNameToCtorName :: Qualified (ProperName 'TypeName) -> Qualified (ProperName 'ConstructorName) + tyNameToCtorName (Qualified qb tNm) = Qualified qb (coerceProperName tNm) + +exprToCoreFn mn ss (Just recT) objUpd@(A.ObjectUpdate obj vs) = wrapTrace ("exprToCoreFn OBJ UPDATE " <> renderValue 100 objUpd) $ do + obj' <- exprToCoreFn mn ss Nothing obj + vs' <- traverse (\(lbl,val) -> exprToCoreFn mn ss Nothing val >>= \val' -> pure (lbl,val')) vs + pure $ + ObjectUpdate + (ssA ss) + recT + obj' + (unchangedRecordFields (fmap fst vs) recT) + vs' + where + -- TODO: Optimize/Refactor Using Data.Set + -- Return the unchanged labels of a closed record, or Nothing for other types or open records. + unchangedRecordFields :: [PSString] -> Type a -> Maybe [PSString] + unchangedRecordFields updated (TypeApp _ (TypeConstructor _ C.Record) row) = + collect row where + collect :: Type a -> Maybe [PSString] + collect (REmptyKinded _ _) = Just [] + collect (RCons _ (Label l) _ r) = (if l `elem` updated then id else (l :)) <$> collect r + collect _ = Nothing + unchangedRecordFields _ _ = Nothing +exprToCoreFn _ _ Nothing objUpd@(A.ObjectUpdate _ _) = + internalError $ "Error while desugaring object update. No type provided for expression:\n" <> renderValue 100 objUpd + +-- Lambda abstraction. See the comments on `instantiatePolyType` above for an explanation of the strategy here. +exprToCoreFn mn _ (Just t) (A.Abs (A.VarBinder ssb name) v) = wrapTrace ("exprToCoreFn " <> showIdent' name) $ + withInstantiatedFunType mn t $ \a b -> do + body <- bindLocalVariables [(ssb,name,a,Defined)] $ exprToCoreFn mn ssb (Just b) v + pure $ Abs (ssA ssb) (function a b) name body +-- By the time we receive the AST, only Lambdas w/ a VarBinder should remain +-- TODO: Better failure message if we pass in 'Nothing' as the (Maybe Type) arg for an Abstraction +exprToCoreFn _ _ t lam@(A.Abs _ _) = + internalError $ "Abs with Binder argument was not desugared before exprToCoreFn: \n" + <> renderValue 100 lam + <> "\n\n" + <> show (ppType 100 <$> t) + <> "\n" + <> show lam + +{- The App case is substantially complicated by our need to correctly type + expressions that contain type class dictionary constructors, specifically expressions like: + + ``` + (C$Dict :: forall x. {method :: x -> (...)}) -> {method :: x -> (..)}) ({method: f}) + ```` + + Because the dictionary ctor and record of methods it is being applied to + are untouched by the PS typechecker, we have to instantiate the + quantified variables to conform with the supplied type. +-} +exprToCoreFn mn ss mTy app@(A.App fun arg) + | isDictCtor fun = wrapTrace "exprToCoreFn APP DICT " $ do + traceM $ "APP Dict type" <> show (ppType 100 <$> mTy) + traceM $ "APP Dict expr:\n" <> renderValue 100 app + let analyzed = mTy >>= analyzeCtor + prettyAnalyzed = bimap (ppType 100) (fmap (ppType 100)) <$> analyzed + traceM $ "APP DICT analyzed:\n" <> show prettyAnalyzed + case mTy of + Just iTy -> + case analyzed of + -- Branch for a "normal" (i.e. non-empty) typeclass dictionary application + Just (TypeConstructor _ (Qualified qb nm), args) -> do + traceM $ "APP Dict name: " <> T.unpack (runProperName nm) + env <- getEnv + case M.lookup (Qualified qb $ coerceProperName nm) (dataConstructors env) of + Just (_, _, ty, _) -> do + traceM $ "APP Dict original type:\n" <> ppType 100 ty + case instantiate ty args of + iFun@(iArg :-> iRes) -> do + traceM $ "APP Dict iArg:\n" <> ppType 100 iArg + traceM $ "APP Dict iRes:\n" <> ppType 100 iRes + fun' <- exprToCoreFn mn ss (Just iFun) fun + arg' <- exprToCoreFn mn ss (Just iArg) arg + pure $ App (ss,[],Nothing) fun' arg' + _ -> error "dict ctor has to have a function type" + _ -> throwError . errorMessage' ss . UnknownName . fmap DctorName $ Qualified qb (coerceProperName nm) + -- This should actually be impossible here, so long as we desugared all the constrained types properly + Just (other,_) -> error $ "APP Dict not a constructor type (impossible here?): \n" <> ppType 100 other + -- Case for handling empty dictionaries (with no methods) + Nothing -> wrapTrace "APP DICT 3" $ do + -- REVIEW: This might be the one place where `kindType` in instantiatePolyType is wrong, check the kinds in the output + -- REVIEW: We might want to match more specifically on both/either the expression and type level to + -- ensure that we are working only with empty dictionaries here. (Though anything else should be caught be the previous case) + let (inner,g,act) = instantiatePolyType mn iTy + act (exprToCoreFn mn ss (Just inner) app) >>= \case + App ann' e1 e2 -> pure . g $ App ann' e1 e2 + _ -> error "An application desguared to something else. This should not be possible." + Nothing -> error $ "APP Dict w/o type passed in (impossible to infer):\n" <> renderValue 100 app + + | otherwise = wrapTrace "exprToCoreFn APP" $ do + traceM $ renderValue 100 app + fun' <- exprToCoreFn mn ss Nothing fun + let funTy = exprType fun' + traceM $ "app fun:\n" <> ppType 100 funTy <> "\n" <> renderExprStr fun' + arg' <- exprToCoreFn mn ss Nothing arg -- We want to keep the original "concrete" arg type + traceM $ "app arg:\n" <> ppType 100 (exprType arg') <> "\n" <> renderExprStr arg' + pure $ App (ss, [], Nothing) fun' arg' + where + isDictCtor = \case + A.Constructor _ (Qualified _ name) -> isDictTypeName name + A.TypedValue _ e _ -> isDictCtor e + _ -> False +-- Dunno what to do here. Haven't encountered an Unused so far, will need to see one to figure out how to handle them +exprToCoreFn _ _ _ (A.Unused _) = -- ????? need to figure out what this _is_ + error "Don't know what to do w/ exprToCoreFn A.Unused" + +exprToCoreFn _ _ (Just ty) (A.Var ss ident@(Qualified _ (GenIdent _ _))) = wrapTrace ("exprToCoreFn VAR (gen) " <> show ident) $ + gets checkEnv >>= \env -> + pure $ Var (ss, [], getValueMeta env ident) (purusTy ty) ident +-- Non-generated Variables should *always* be bound & typed in the Environment before we encounter them. +-- NOTE: Not sure if we should ignore a type passed in? Generally we shouldn't *pass* types here, but bind variables +exprToCoreFn _ _ _ (A.Var ss ident) = wrapTrace ("exprToCoreFn VAR " <> show ident) $ + gets checkEnv >>= \env -> case lookupValue env ident of + Just (ty,_,_) -> pure $ Var (ss, [], getValueMeta env ident) (purusTy ty) ident + Nothing -> lookupDictType ident >>= \case + Just ty -> pure $ Var (ss, [], getValueMeta env ident) (purusTy ty) ident + Nothing -> internalError $ "No known type for identifier " <> show ident + +exprToCoreFn _ _ mty expr@(A.Var ss ident) = internalError + $ "Internal compiler error (exprToCoreFn var fail): Cannot synthesize type for var " + <> show expr + <> "\nSupplied type: " + <> show (ppType 100 <$> mty) + +-- If-Then-Else Turns into a case expression +exprToCoreFn mn ss (Just resT) (A.IfThenElse cond th el) = wrapTrace "exprToCoreFn IFTE" $ do + condE <- exprToCoreFn mn ss (Just tyBoolean) cond + thE <- exprToCoreFn mn ss (Just resT) th + elE <- exprToCoreFn mn ss (Just resT) el + pure $ Case (ss, [], Nothing) resT [condE] + [ CaseAlternative [LiteralBinder (ssAnn ss) $ BooleanLiteral True] + (Right thE) + , CaseAlternative [NullBinder (ssAnn ss)] + (Right elE) ] +exprToCoreFn _ _ Nothing ifte@(A.IfThenElse _ _ _) = + internalError $ "Error while desugaring If-then-else expression. No type provided for:\n " <> renderValue 100 ifte + +-- Constructor case is straightforward, we should already have all of the type info +exprToCoreFn _ _ (Just ctorTy) (A.Constructor ss name) = wrapTrace ("exprToCoreFn CTOR " <> show name) $ do + ctorMeta <- flip getConstructorMeta name <$> getEnv + pure $ Var (ss, [], Just ctorMeta) (purusTy ctorTy) $ fmap properToIdent name +exprToCoreFn _ _ Nothing ctor@(A.Constructor _ _) = + internalError $ "Error while desugaring Constructor expression. No type provided for:\n" <> renderValue 100 ctor - numConstructors - :: (Qualified (ProperName 'ConstructorName), (DataDeclType, ProperName 'TypeName, SourceType, [Ident])) - -> Int - numConstructors ty = length $ filter (((==) `on` typeConstructor) ty) $ M.toList $ dataConstructors env - - typeConstructor - :: (Qualified (ProperName 'ConstructorName), (DataDeclType, ProperName 'TypeName, SourceType, [Ident])) - -> (ModuleName, ProperName 'TypeName) - typeConstructor (Qualified (ByModuleName mn') _, (_, tyCtor, _, _)) = (mn', tyCtor) - typeConstructor _ = internalError "Invalid argument to typeConstructor" - --- | Find module names from qualified references to values. This is used to --- ensure instances are imported from any module that is referenced by the --- current module, not just from those that are imported explicitly (#667). -findQualModules :: [A.Declaration] -> [ModuleName] -findQualModules decls = - let (f, _, _, _, _) = everythingOnValues (++) fqDecls fqValues fqBinders (const []) (const []) - in f `concatMap` decls +{- Case Expressions + + For ordinary case expressions (i.e. those not generated by the compiler during guard desugaring), + the type can be determined by the type of a top-level declaration or + explicit type annotation (which may be either supplied by the user or inferred by the + PS typechecker) and therefore should be passed explicitly. + + For compiler-generated case expressions (specifically: those generated during case/guard desugaring - + some get generated during typeclass desugaring but we have special machinery to ensure that + those types can be synthesized), we cannot be sure that the whole case expression has an explicit + type annotation, so we try to deduce the type from the types of the alternative branches. + + NOTE: This is kind of a hack to let us reuse (rather than rewrite) the existing case/guard + desugaring machinery. In order to correctly type the generated `let` bindings + (see Language.PureScript.Sugar.CaseDeclarations), we must manually construct a polymorphic + type that the PS typechecker cannot infer or deduce. We cannot construct such a type without + the initial PS typechecker pass. We could write two nearly-identical versions of the + case desugaring machinery and try to run the typechecker twice, but that adds a lot of + complexity (machinery is complicated) and would not be good for performance (typechecking + and inference have bad complexity). +-} +exprToCoreFn mn ss (Just caseTy) astCase@(A.Case vs alts) = wrapTrace "exprToCoreFn CASE" $ do + traceM $ "CASE:\n" <> renderValue 100 astCase + traceM $ "CASE TY:\n" <> show (ppType 100 caseTy) + (vs',ts) <- unzip <$> traverse (exprToCoreFn mn ss Nothing >=> (\ e -> pure (e, exprType e))) vs -- extract type information for the *scrutinees* + alts' <- traverse (altToCoreFn mn ss caseTy ts) alts -- see explanation in altToCoreFn. We pass in the types of the scrutinee(s) + pure $ Case (ssA ss) (purusTy caseTy) vs' alts' +exprToCoreFn mn ss Nothing astCase@(A.Case vs alts@(alt:_)) = wrapTrace "exprToCoreFn CASE (no type)" $ do + case alt of + A.CaseAlternative _ (A.GuardedExpr _ body1:_) -> do + caseTy <- exprType <$> exprToCoreFn mn ss Nothing body1 + traceM $ "CASE:\n" <> renderValue 100 astCase + traceM $ "CASE TY:\n" <> show (ppType 100 caseTy) + (vs',ts) <- unzip <$> traverse (exprToCoreFn mn ss Nothing >=> (\ e -> pure (e, exprType e))) vs -- extract type information for the *scrutinees* + alts' <- traverse (altToCoreFn mn ss caseTy ts) alts -- see explanation in altToCoreFn. We pass in the types of the scrutinee(s) + pure $ Case (ssA ss) (purusTy caseTy) vs' alts' + _ -> internalError $ "Error while desugaring Case expression. Could not synthesize type of: " <> renderValue 100 astCase +exprToCoreFn _ _ Nothing astCase@(A.Case _ _) = + internalError $ "Error while desugaring Case expression. No type provided for:\n" <> renderValue 100 astCase + +-- We prioritize the supplied type over the inferred type, since a type should only ever be passed when known to be correct. +exprToCoreFn mn ss (Just ty) (A.TypedValue _ v _) = wrapTrace "exprToCoreFn TV1" $ + exprToCoreFn mn ss (Just ty) v +-- If we encounter a TypedValue w/o a supplied type, we use the annotated type +exprToCoreFn mn ss Nothing (A.TypedValue _ v ty) = wrapTrace "exprToCoreFn TV2" $ + exprToCoreFn mn ss (Just ty) v + +-- Complicated. See `transformLetBindings` +exprToCoreFn mn ss _ (A.Let w ds v) = wrapTrace "exprToCoreFn LET" $ case NE.nonEmpty ds of + Nothing -> error "declarations in a let binding can't be empty" + Just _ -> do + (decls,expr) <- transformLetBindings mn ss [] ds v + pure $ Let (ss, [], getLetMeta w) decls expr + +-- Pretty sure we should prefer the positioned SourceSpan +exprToCoreFn mn _ ty (A.PositionedValue ss _ v) = wrapTrace "exprToCoreFn POSVAL" $ + exprToCoreFn mn ss ty v +-- Function should never reach this case, but there are a lot of AST Expressions that shouldn't ever appear here, so +-- we use a catchall case. +exprToCoreFn _ ss _ e = + internalError + $ "Unexpected value in exprToCoreFn:\n" + <> renderValue 100 e + <> "at position:\n" + <> show ss + +-- Desugars case alternatives from AST to CoreFn representation. +altToCoreFn :: forall m + . M m + => ModuleName + -> SourceSpan + -> SourceType -- The "return type", i.e., the type of the expr to the right of the -> in a case match branch (we always know this) + -> [SourceType] -- The types of the *scrutinees*, i.e. the `x` in `case x of (...)`. NOTE: Still not sure why there can be more than one + -> A.CaseAlternative + -> m (CaseAlternative Ann) +altToCoreFn mn ss ret boundTypes (A.CaseAlternative bs vs) = wrapTrace "altToCoreFn" $ do + env <- gets checkEnv + bTypes <- M.unions <$> zipWithM inferBinder' boundTypes bs -- Inferring the types for binders requires some special machinery & knowledge of the scrutinee type. NOTE: Not sure why multiple binders? + let toBind = (\(n',(ss',ty')) -> (ss',n',ty',Defined)) <$> M.toList bTypes + binders = binderToCoreFn env mn ss <$> bs + traceM $ concatMap (\x -> show x <> "\n") toBind + ege <- go toBind vs + pure $ CaseAlternative binders ege + where + go :: [(SourceSpan, Ident, SourceType, NameVisibility)] -> [A.GuardedExpr] -> m (Either [(Guard Ann, Expr Ann)] (Expr Ann)) + go toBind [A.MkUnguarded e] = wrapTrace "altToCoreFn GO" $ do + expr <- bindLocalVariables toBind $ exprToCoreFn mn ss (Just ret) e -- need to bind all variables that occur in the binders. We know the type of the right hand side (as it was passed in) + pure $ Right expr + -- NOTE: Not sure whether this works / TODO: Make a test case that uses guards in case expressions + go toBind gs = bindLocalVariables toBind $ do + ges <- forM gs $ \case + A.GuardedExpr g e -> do + let cond = guardToExpr g + condE <- exprToCoreFn mn ss (Just tyBoolean) cond -- (Just tyBoolean)? + eE <- exprToCoreFn mn ss (Just ret) e + pure (condE,eE) + pure . Left $ ges + guardToExpr [A.ConditionGuard cond] = cond + guardToExpr _ = internalError "Guard not correctly desugared" + + +transformLetBindings :: forall m. M m => ModuleName -> SourceSpan -> [Bind Ann] -> [A.Declaration] -> A.Expr -> m ([Bind Ann], Expr Ann) +transformLetBindings mn ss seen [] ret = (seen,) <$> withBindingGroupVisible (exprToCoreFn mn ss Nothing ret) +transformLetBindings mn _ss seen ((A.ValueDecl sa@(ss,_) ident nameKind [] [A.MkUnguarded (A.TypedValue checkType val ty)]) : rest) ret = + wrapTrace ("transformLetBindings VALDEC TYPED " <> showIdent' ident <> " :: " <> ppType 100 ty ) $ + bindNames (M.singleton (Qualified (BySourcePos $ spanStart ss) ident) (ty, nameKind, Defined)) $ do + thisDecl <- declToCoreFn mn (A.ValueDecl sa ident nameKind [] [A.MkUnguarded (A.TypedValue checkType val ty)]) + let seen' = seen ++ thisDecl + transformLetBindings mn _ss seen' rest ret +transformLetBindings mn _ss seen (A.ValueDecl (ss,_) ident nameKind [] [A.MkUnguarded val] : rest) ret = wrapTrace ("transformLetBindings VALDEC " <> showIdent' ident <> " = " <> renderValue 100 val) $ do + e <- exprToCoreFn mn ss Nothing val + let ty = exprType e + if not (containsUnknowns ty) -- TODO: Don't need this anymore (shouldn't ever contain unknowns) + then bindNames (M.singleton (Qualified (BySourcePos $ spanStart ss) ident) (ty, nameKind, Defined)) $ do + let thisDecl = [NonRec (ssA ss) ident e] + let seen' = seen ++ thisDecl + transformLetBindings mn _ss seen' rest ret + else error + $ "The inferred type for let-bound identifier \n '" + <> showIdent' ident + <> "'\ncontains unification variables:\n " + <> ppType 1000 ty + <> "\nIf this let-bound identifier occurs in a user-defined `let-binding`, please add a type signature for '" <> showIdent' ident <> "'" + <> "\nIf the identifier occurs in a compiler-generated `let-binding` with guards (e.g. in a guarded case branch), try removing the guarded expression (e.g. use a normal if-then expression)" +-- NOTE/TODO: This is super hack-ey. Ugh. +transformLetBindings mn _ss seen (A.BindingGroupDeclaration ds : rest) ret = wrapTrace "transformLetBindings BINDINGGROUPDEC" $ do + -- All of the types in the binding group should be TypedValues (after my modifications to the typechecker) + -- NOTE: We re-implement part of TypeChecker.Types.typeDictionaryForBindingGroup here because it *could* try to do + -- type checking/inference, which we want to avoid (because it mangles our types) + let types = go <$> NEL.toList ((\(i, _, v) -> (i, v)) <$> ds) + case sequence types of + Right typed -> do + let ds' = flip map typed $ \((sann,iden),(expr,ty)) -> A.ValueDecl sann iden Private [] [A.MkUnguarded (A.TypedValue False expr ty)] + dict = M.fromList $ flip map typed $ \(((ss,_),ident),(_,ty)) -> (Qualified (BySourcePos $ spanStart ss) ident, (ty, Private, Undefined)) + bindNames dict $ do + makeBindingGroupVisible + thisDecl <- concat <$> traverse (declToCoreFn mn) ds' + let seen' = seen ++ thisDecl + transformLetBindings mn _ss seen' rest ret + -- Because this has already been through the typechecker once, every value in the binding group should have an explicit type. I hope. + Left _ -> error + $ "untyped binding group element in mutually recursive LET binding group after initial typechecker pass: \n" + <> LT.unpack (pShow $ lefts types) + where + go :: ((SourceAnn, Ident), A.Expr) -> Either ((SourceAnn,Ident), A.Expr) ((SourceAnn, Ident), (A.Expr, SourceType)) + go (annName,A.TypedValue _ expr ty) = Right (annName,(expr,ty)) + go (annName,other) = Left (annName,other) +transformLetBindings _ _ _ _ _ = error "Invalid argument to TransformLetBindings" + + +-- | Infer the types of variables brought into scope by a binder *without* instantiating polytypes to unknowns. +-- TODO: Check whether unifyTypes needed +inferBinder' + :: forall m + . (MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) + => SourceType + -> A.Binder + -> m (M.Map Ident (SourceSpan, SourceType)) +inferBinder' _ A.NullBinder = return M.empty +inferBinder' _ (A.LiteralBinder _ (StringLiteral _)) = wrapTrace "inferBinder' STRLIT" $ return M.empty +inferBinder' _ (A.LiteralBinder _ (CharLiteral _)) = wrapTrace "inferBinder' CHARLIT" $ return M.empty +inferBinder' _ (A.LiteralBinder _ (NumericLiteral (Left _))) = wrapTrace "inferBinder' LITINT" $ return M.empty +inferBinder' _ (A.LiteralBinder _ (NumericLiteral (Right _))) = wrapTrace "inferBinder' NUMBERLIT" $ return M.empty +inferBinder' _ (A.LiteralBinder _ (BooleanLiteral _)) = wrapTrace "inferBinder' BOOLLIT" $ return M.empty +inferBinder' val (A.VarBinder ss name) = wrapTrace ("inferBinder' VAR " <> T.unpack (runIdent name)) $ return $ M.singleton name (ss, val) +inferBinder' val (A.ConstructorBinder ss ctor binders) = wrapTrace ("inferBinder' CTOR: " <> show ctor) $ do + traceM $ "InferBinder VAL:\n" <> ppType 100 val + env <- getEnv + let cArgs = ctorArgs val + traceM $ "InferBinder CTOR ARGS:\n" <> concatMap (\x -> ppType 100 x <> "\n") cArgs + case M.lookup ctor (dataConstructors env) of + Just (_, _, _ty, _) -> do + let ty = instantiate _ty cArgs + traceM $ "InferBinder CTOR TY:\n" <> ppType 100 ty + let (args, _) = peelArgs ty + traceM $ "InferBinder ARGS:\n" <> concatMap (\x -> ppType 100 x <> "\n") args + M.unions <$> zipWithM inferBinder' (reverse args) binders + _ -> throwError . errorMessage' ss . UnknownName . fmap DctorName $ ctor + where + peelArgs :: Type a -> ([Type a], Type a) + peelArgs = go [] + where + go args (TypeApp _ (TypeApp _ fn arg) ret) | eqType fn tyFunction = go (arg : args) ret + go args ret = (args, ret) +inferBinder' val (A.LiteralBinder _ (ObjectLiteral props)) = wrapTrace "inferBinder' OBJECTLIT" $ do + traceM $ ppType 100 val + let props' = sortOn fst props + case unwrapRecord val of + Left notARecord -> error + $ "Internal error while desugaring binders to CoreFn: \nType " + <> ppType 100 notARecord + <> "\n is not a record type" + Right rowItems -> do + let typeKeys = S.fromList $ fst <$> rowItems + exprKeys = S.fromList $ fst <$> props' + -- The type-level labels are authoritative + diff = S.difference typeKeys exprKeys + if S.null diff + then deduceRowProperties (M.fromList rowItems) props' + else error $ "Error. Object literal in a pattern match is missing fields: " <> show diff where - fqDecls :: A.Declaration -> [ModuleName] - fqDecls (A.TypeInstanceDeclaration _ _ _ _ _ _ q _ _) = getQual' q - fqDecls (A.ValueFixityDeclaration _ _ q _) = getQual' q - fqDecls (A.TypeFixityDeclaration _ _ q _) = getQual' q - fqDecls _ = [] - - fqValues :: A.Expr -> [ModuleName] - fqValues (A.Var _ q) = getQual' q - fqValues (A.Constructor _ q) = getQual' q - fqValues _ = [] - - fqBinders :: A.Binder -> [ModuleName] - fqBinders (A.ConstructorBinder _ q _) = getQual' q - fqBinders _ = [] - - getQual' :: Qualified a -> [ModuleName] - getQual' = maybe [] return . getQual - --- | Desugars import declarations from AST to CoreFn representation. -importToCoreFn :: A.Declaration -> Maybe (Ann, ModuleName) -importToCoreFn (A.ImportDeclaration (ss, com) name _ _) = Just ((ss, com, Nothing), name) -importToCoreFn _ = Nothing - --- | Desugars foreign declarations from AST to CoreFn representation. -externToCoreFn :: A.Declaration -> Maybe Ident -externToCoreFn (A.ExternDeclaration _ name _) = Just name -externToCoreFn _ = Nothing - --- | Desugars export declarations references from AST to CoreFn representation. --- CoreFn modules only export values, so all data constructors, instances and --- values are flattened into one list. -exportToCoreFn :: A.DeclarationRef -> [Ident] -exportToCoreFn (A.TypeRef _ _ (Just dctors)) = fmap properToIdent dctors -exportToCoreFn (A.TypeRef _ _ Nothing) = [] -exportToCoreFn (A.TypeOpRef _ _) = [] -exportToCoreFn (A.ValueRef _ name) = [name] -exportToCoreFn (A.ValueOpRef _ _) = [] -exportToCoreFn (A.TypeClassRef _ _) = [] -exportToCoreFn (A.TypeInstanceRef _ name _) = [name] -exportToCoreFn (A.ModuleRef _ _) = [] -exportToCoreFn (A.ReExportRef _ _ _) = [] - --- | Converts a ProperName to an Ident. -properToIdent :: ProperName a -> Ident -properToIdent = Ident . runProperName + deduceRowProperties :: M.Map PSString SourceType -> [(PSString,A.Binder)] -> m (M.Map Ident (SourceSpan,SourceType)) + deduceRowProperties _ [] = pure M.empty + deduceRowProperties types ((lbl,bndr):rest) = case M.lookup lbl types of + Nothing -> error $ "Cannot deduce type information for record with label " <> show lbl -- should be impossible after typechecking + Just ty -> do + x <- inferBinder' ty bndr + xs <- deduceRowProperties types rest + pure $ M.union x xs +-- TODO: Remove ArrayT pattern synonym +inferBinder' (ArrayT val) (A.LiteralBinder _ (ArrayLiteral binders)) = wrapTrace "inferBinder' ARRAYLIT" $ M.unions <$> traverse (inferBinder' val) binders +inferBinder' _ (A.LiteralBinder _ (ArrayLiteral _)) = internalError "bad type in array binder " +inferBinder' val (A.NamedBinder ss name binder) = wrapTrace ("inferBinder' NAMEDBINDER " <> T.unpack (runIdent name)) $ + warnAndRethrowWithPositionTC ss $ do + m <- inferBinder' val binder + return $ M.insert name (ss, val) m +inferBinder' val (A.PositionedBinder pos _ binder) = wrapTrace "inferBinder' POSITIONEDBINDER" $ + warnAndRethrowWithPositionTC pos $ inferBinder' val binder +inferBinder' _ (A.TypedBinder ty binder) = wrapTrace "inferBinder' TYPEDBINDER" $ do + (elabTy, _) <- kindOf ty + inferBinder' elabTy binder +inferBinder' _ A.OpBinder{} = + internalError "OpBinder should have been desugared before inferBinder'" +inferBinder' _ A.BinaryNoParensBinder{} = + internalError "BinaryNoParensBinder should have been desugared before inferBinder'" +inferBinder' _ A.ParensInBinder{} = + internalError "ParensInBinder should have been desugared before inferBinder'" diff --git a/src/Language/PureScript/CoreFn/Desugar/Utils.hs b/src/Language/PureScript/CoreFn/Desugar/Utils.hs new file mode 100644 index 000000000..bfd73079c --- /dev/null +++ b/src/Language/PureScript/CoreFn/Desugar/Utils.hs @@ -0,0 +1,657 @@ +{- HLINT ignore "Use void" -} +{- HLINT ignore "Use <$" -} +{- HLINT ignore "Use <&>" -} +module Language.PureScript.CoreFn.Desugar.Utils where + +import Prelude +import Protolude (MonadError (..), traverse_) + +import Data.Function (on) +import Data.Tuple (swap) +import Data.Map qualified as M + +import Language.PureScript.AST qualified as A +import Language.PureScript.AST.Literals (Literal(..)) +import Language.PureScript.AST.SourcePos (pattern NullSourceSpan, SourceSpan(..)) +import Language.PureScript.AST.Traversals (everythingOnValues, overTypes) +import Language.PureScript.CoreFn.Ann (Ann) +import Language.PureScript.CoreFn.Binders (Binder(..)) +import Language.PureScript.CoreFn.Expr (Expr(..), PurusType) +import Language.PureScript.CoreFn.Meta (ConstructorType(..), Meta(..)) +import Language.PureScript.Crash (internalError) +import Language.PureScript.Environment ( + pattern RecordT, + DataDeclType(..), + Environment(..), + NameKind(..), + lookupConstructor, + lookupValue, + NameVisibility (..), + dictTypeName, + TypeClassData (typeClassArguments), + function, + pattern (:->), + isDictTypeName) +import Language.PureScript.Names (Ident(..), ModuleName, ProperName(..), ProperNameType(..), Qualified(..), QualifiedBy(..), getQual, runIdent, coerceProperName) +import Language.PureScript.Types (SourceType, Type(..), Constraint (..), srcTypeConstructor, srcTypeApp, rowToSortedList, RowListItem(..), replaceTypeVars, everywhereOnTypes) +import Control.Monad.Supply.Class (MonadSupply) +import Control.Monad.State.Strict (MonadState, gets, modify') +import Control.Monad.Writer.Class ( MonadWriter ) +import Language.PureScript.TypeChecker.Types + ( kindType ) +import Language.PureScript.Errors + ( MultipleErrors ) +import Debug.Trace (traceM, trace) +import Data.Text qualified as T +import Text.Pretty.Simple (pShow) +import Data.Text.Lazy qualified as LT +import Language.PureScript.TypeChecker.Monad + ( bindLocalVariables, + getEnv, + withScopedTypeVars, + CheckState(checkCurrentModule, checkEnv), debugNames ) +import Language.PureScript.PSString (PSString) +import Language.PureScript.Label (Label(..)) +import Data.Bifunctor (Bifunctor(..)) +import Data.List.NonEmpty qualified as NEL +import Language.PureScript.TypeClassDictionaries (NamedDict, TypeClassDictionaryInScope (..)) +import Data.List (foldl') +import Language.PureScript.AST.Traversals (litM) +import Control.Lens.Plated +import Language.PureScript.Sugar (desugarGuardedExprs) +import Language.PureScript.AST.Declarations (declSourceSpan) + + +{- UTILITIES -} +--TODO: Explain purpose of every function + + +-- | Type synonym for a monad that has all of the required typechecker functionality +type M m = (MonadSupply m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) + + + +{- "Type Constructor analysis" machinery. (This requires some explaining) + + In the course of converting to typed CoreFn, we always proceed "top-down" + from top-level declarations which must have a type annotation attached + (their typechecker enforces this - it will add an inferred annotation if + the user fails to annotate the type). + + Because not all sub-expression (specifically, "synthetic applications" where a type class + dictionary constructor is applied to its argument in an instance declaration) are typed, + we may run into situations where the inferred or reconstructed type for a sub-expression + is universally quantified, even though we know (via our "top-down" approach) that the + quantified type variables should be instantiated (either to concrete types or to + type variables which are introduced in the outer lexical scope). + + An example (from test 4310) makes the problem clearer. Suppose we have: + + ``` + data Tuple a b = Tuple a b + + infixr 6 Tuple as /\ + infixr 6 type Tuple as /\ + + mappend :: String -> String -> String + mappend _ _ = "mappend" + + infixr 5 mappend as <> + + class Test a where + runTest :: a -> String + + instance Test Int where + runTest _ = "4" + + instance (Test a, Test b) => Test (a /\ b) where + runTest (a /\ b) = runTest a <> runTest b + + ``` + + The generated code for the typeclass declaration gives us (in part): + + ``` + Test$Dict :: forall a. { runTest :: a -> String } -> { runTest :: a -> String } + Test$Dict = \(x: { runTest :: a -> String} ) -> + (x: { runTest :: a -> String} ) + + runTest :: forall (@a :: Type). Test$Dict a -> a -> String + runTest = \(dict: Test$Dict a) -> + case (dict: Test$Dict a) of + (Test$Dict v) -> (v: { runTest :: a -> String} ).runTest + ``` + + Because the Tuple instance for Test uses `runTest` (the function), and because + `runTest` is universally quantified, if we did not instantiate those quantifiers, + a new skolem scope will be introduced at each application of `runTest`, giving us + type variables that cannot be unified with the outermost type variables. + + That is, without using this machiner (and `instantiate`), we end up with something like + this for the tuple instance: + + ``` + test/\ :: forall (a :: Type) (b :: Type). Test$Dict a -> Test$Dict b -> Test$Dict (Tuple a b) + test/\ = \(dictTest: Test$Dict a) -> + \(dictTest1: Test$Dict b) -> + (Test$Dict: { runTest :: a -> String} -> Test$Dict a ) { runTest: \(v: Tuple a0 b1) -> } + case (v: Tuple a0 b1) of + (Tuple a b) -> + ((mappend: String -> String -> String) + (((runTest: forall (@a :: Type). Test$Dict a -> a -> String) (dictTest: Test$Dict a)) (a: t1))) + (((runTest: forall (@a :: Type). Test$Dict a -> a -> String) (dictTest1: Test$Dict b)) (b: t2)) + ``` + + By using this machinery in `inferBinder'`, we can instantiate the quantifiers to the + lexically scoped type variables in the top-level signature, and get output that is properly typed: + + ``` + test/\ :: forall (a :: Type) (b :: Type). Test$Dict a -> Test$Dict b -> Test$Dict (Tuple a b) + test/\ = \(dictTest: Test$Dict a) -> + \(dictTest1: Test$Dict b) -> + (Test$Dict: { runTest :: Tuple a b -> String} -> Test$Dict (Tuple a b) ) { runTest: \(v: Tuple a b) -> } + case (v: Tuple a b) of + (Tuple a b) -> + ((mappend: String -> String -> String) + (((runTest: forall (@a :: Type). Test$Dict a -> a -> String) (dictTest: Test$Dict a)) (a: a))) + (((runTest: forall (@a :: Type). Test$Dict a -> a -> String) (dictTest1: Test$Dict b)) (b: b)) + + ``` + + We also use this in the branch of the `App` case of `exprToCoreFn` that handles dictionary applications + (in the same manner and for the same purpose). + +-} + +-- Given a type (which we expect to be a TyCon applied to type args), +-- extract (TyCon,[Args]) (returning Nothing if the input type is not a TyCon) +analyzeCtor :: SourceType -> Maybe (SourceType,[SourceType]) +analyzeCtor t = (,ctorArgs t) <$> ctorFun t + +-- Extract all of the arguments to a type constructor +ctorArgs :: SourceType -> [SourceType] +ctorArgs (TypeApp _ t1 t2) = ctorArgs t1 <> [t2] +ctorArgs _ = [] + +-- Extract the TyCon ("function") part of an applied Type Constructor +ctorFun :: SourceType -> Maybe SourceType +ctorFun (TypeApp _ t1 _) = go t1 + where + go (TypeApp _ tx _) = case ctorFun tx of + Nothing -> Just tx + Just tx' -> Just tx' + go other = Just other +ctorFun _ = Nothing + + +{- Instantiation machinery. This differs from `instantiatePolyType` and + `withInstantiatedFunType` in that those functions are used to "peek under" + the quantifier in a universally quantified type (i.e. those functions + *put the quantifier back* after temporarily instantiating the quantified variables + *to type variables* for the purposes of type reconstruction). + + This instantiates a quantified type (the first arg) and *does not* replace the + quantifier. This is primarily used when we encounter an expression with a universally + quantified type (either as an annotation in a AST.TypedValue or as the result of looking up + the type in the typechecking environment) in a context where we know (from our top-down approach) + that the instantiated type must be instantiated to something "concrete" (where, again, + a "concrete" type can either be an explicit type or a tyvar from the outer scope). +-} +instantiate :: SourceType -> [SourceType] -> SourceType +instantiate ty [] = ty +instantiate (ForAll _ _ var _ inner _) (t:ts) = replaceTypeVars var t $ instantiate inner ts +instantiate other _ = other + +-- | Traverse a literal. Note that literals are usually have a type like `Literal (Expr a)`. That is: The `a` isn't typically an annotation, it's an expression type +traverseLit :: forall m a b. Applicative m => (a -> m b) -> Literal a -> m (Literal b) +traverseLit f = \case + NumericLiteral x -> pure $ NumericLiteral x + StringLiteral x -> pure $ StringLiteral x + CharLiteral x -> pure $ CharLiteral x + BooleanLiteral x -> pure $ BooleanLiteral x + ArrayLiteral xs -> ArrayLiteral <$> traverse f xs + ObjectLiteral xs -> ObjectLiteral <$> traverse (\(str,x) -> (str,) <$> f x) xs + + +-- Wrapper around instantiatePolyType to provide a better interface +withInstantiatedFunType :: M m => ModuleName -> SourceType -> (SourceType -> SourceType -> m (Expr Ann)) -> m (Expr Ann) +withInstantiatedFunType mn ty act = case instantiatePolyType mn ty of + (a :-> b, replaceForalls, bindAct) -> bindAct $ replaceForalls <$> act a b + (other,_,_) -> let !showty = LT.unpack (pShow other) + in error $ "Internal error. Expected a function type, but got: " <> showty +{- This function more-or-less contains our strategy for handling polytypes (quantified or constrained types). It returns a tuple T such that: + - T[0] is the inner type, where all of the quantifiers and constraints have been removed. We just instantiate the quantified type variables to themselves (I guess?) - the previous + typchecker passes should ensure that quantifiers are all well scoped and that all essential renaming has been performed. Typically, the inner type should be a function. + Constraints are eliminated by replacing the constraint argument w/ the appropriate dictionary type. + + - T[1] is a function to transform the eventual expression such that it is properly typed. Basically: It puts the quantifiers back, (hopefully) in the right order and with + the correct visibility, skolem scope, etc. + + - T[2] is a monadic action which binds local variables or type variables so that we can use type inference machinery on the expression corresponding to this type. + NOTE: The only local vars this will bind are "dict" identifiers introduced to type desguared typeclass constraints. + That is: If you're using this on a function type, you'll still have to bind the antecedent type to the + identifier bound in the VarBinder. +-} +-- TODO: Explicitly return two sourcetypes for arg/return types +instantiatePolyType :: M m => ModuleName -> SourceType-> (SourceType, Expr b -> Expr b, m a -> m a) +instantiatePolyType mn = \case + ForAll ann vis var mbk t mSkol -> case instantiatePolyType mn t of + (inner,g,act) -> + let f = \case + Abs ann' ty' ident' expr' -> + Abs ann' (ForAll ann vis var (purusTy <$> mbk) (purusTy ty') mSkol) ident' expr' + other -> other + -- FIXME: kindType? + act' ma = withScopedTypeVars mn [(var,kindType)] $ act ma -- NOTE: Might need to pattern match on mbk and use the real kind (though in practice this should always be of kind Type, I think?) + in (inner, f . g, act') + fun@(a :-> _) -> case analyzeCtor a of + Just (TypeConstructor _ (Qualified _ nm), _) -> + if isDictTypeName nm + then + let act' ma = bindLocalVariables [(NullSourceSpan,Ident "dict",a,Defined)] ma + in (fun,id,act') + else (fun,id,id) + _ -> (fun,id,id) + other -> (other,id,id) + +-- In a context where we expect a Record type (object literals, etc), unwrap the record and get at the underlying rowlist +unwrapRecord :: Type a -> Either (Type a) [(PSString,Type a)] +unwrapRecord = \case + RecordT lts -> Right $ go <$> fst (rowToSortedList lts) + other -> Left other + where + go :: RowListItem a -> (PSString, Type a) + go RowListItem{..} = (runLabel rowListLabel, rowListType) + +traceNameTypes :: M m => m () +traceNameTypes = do + nametypes <- getEnv >>= pure . debugNames + traverse_ traceM nametypes + +desugarCasesEverywhere :: M m => A.Declaration -> m (A.Declaration) +desugarCasesEverywhere d = traverseDeclBodies (transformM $ desugarGuardedExprs (declSourceSpan d )) d + + +traverseDeclBodies :: forall m. Applicative m => (A.Expr -> m A.Expr) -> A.Declaration -> m A.Declaration +traverseDeclBodies f = \case + A.BindingGroupDeclaration decls -> + A.BindingGroupDeclaration + <$> traverse go {- (\(annIdent,nk,expr) -> f expr >>= \e -> pure (annIdent,nk,e)) -} decls + A.ValueDecl ann name nk bs [A.MkUnguarded e] -> + (\x -> A.ValueDecl ann name nk bs [A.MkUnguarded x]) <$> f e + other -> pure other + where + go :: ((A.SourceAnn, Ident), NameKind, A.Expr) -> m ((A.SourceAnn, Ident), NameKind, A.Expr) + go (annid, nk, e) = (\ex -> (annid, nk, ex)) <$> f e + + +instance Plated A.Expr where + plate f = \case + A.Literal ss litE -> A.Literal ss <$> traverseLit f litE + A.UnaryMinus ss e -> A.UnaryMinus ss <$> f e + A.BinaryNoParens a b c -> A.BinaryNoParens <$> f a <*> f b <*> f c + A.Parens e -> A.Parens <$> f e + A.Accessor str e -> A.Accessor str <$> f e + A.ObjectUpdate e fs -> A.ObjectUpdate <$> f e <*> (traverse . traverse) f fs + A.ObjectUpdateNested e pt -> A.ObjectUpdateNested <$> f e <*> traverse f pt + A.Abs b e -> A.Abs b <$> f e + A.App e1 e2 -> A.App <$> f e1 <*> f e2 + A.VisibleTypeApp e t -> (\ex -> A.VisibleTypeApp ex t) <$> f e + A.Unused e -> A.Unused <$> f e + A.Var ss i -> pure $ A.Var ss i + A.Op ss nm -> pure $ A.Op ss nm + A.IfThenElse c e1 e2 -> A.IfThenElse <$> f c <*> f e1 <*> f e2 + A.Constructor ss nm -> pure $ A.Constructor ss nm + A.Case es alts -> A.Case <$> traverse f es <*> traverse goAlt alts + A.TypedValue b e t -> (\ex -> A.TypedValue b ex t) <$> f e + A.Let wp decls e -> A.Let wp <$> traverse (traverseDeclBodies f) decls <*> f e + A.Do mn doElems -> A.Do mn <$> traverse goDoElem doElems + A.Ado mn dElems e -> A.Ado mn <$> traverse goDoElem dElems <*> f e + A.PositionedValue ss cs e -> A.PositionedValue ss cs <$> f e + other -> pure other + where + goAlt = \case + A.CaseAlternative bs ges -> A.CaseAlternative bs <$> traverse goGE ges + goGE (A.GuardedExpr gs e) = A.GuardedExpr <$> traverse goGuard gs <*> f e + goGuard = \case + A.ConditionGuard e -> A.ConditionGuard <$> f e + A.PatternGuard b e -> A.PatternGuard b <$> f e + goDoElem = \case + A.DoNotationValue e -> A.DoNotationValue <$> f e + A.DoNotationBind b e -> A.DoNotationBind b <$> f e + A.DoNotationLet decls -> A.DoNotationLet <$> traverse (traverseDeclBodies f) decls + A.PositionedDoNotationElement ss cs de -> A.PositionedDoNotationElement ss cs <$> goDoElem de + + + + + +{- Since we operate on an AST where constraints have been desugared to dictionaries at the *expr* level, + using a typechecker context which contains ConstrainedTypes, looking up the type for a class method + will always give us a "wrong" type. Let's try fixing them in the context! +-} +desugarConstraintType :: SourceType -> SourceType +desugarConstraintType = \case + ForAll a vis var mbk t mSkol -> + let t' = desugarConstraintType t + in ForAll a vis var mbk t' mSkol + ConstrainedType _ Constraint{..} t -> + let inner = desugarConstraintType t + dictTyName :: Qualified (ProperName 'TypeName) = dictTypeName . coerceProperName <$> constraintClass + dictTyCon = srcTypeConstructor dictTyName + dictTy = foldl srcTypeApp dictTyCon constraintArgs + in function dictTy inner + other -> other + +desugarConstraintTypes :: M m => m () +desugarConstraintTypes = do + env <- getEnv + let f = everywhereOnTypes desugarConstraintType + + oldNameTypes = names env + desugaredNameTypes = (\(st,nk,nv) -> (f st,nk,nv)) <$> oldNameTypes + + oldTypes = types env + desugaredTypes = first f <$> oldTypes + + oldCtors = dataConstructors env + desugaredCtors = (\(a,b,c,d) -> (a,b,f c,d)) <$> oldCtors + + oldSynonyms = typeSynonyms env + desugaredSynonyms = second f <$> oldSynonyms + + newEnv = env { names = desugaredNameTypes + , types = desugaredTypes + , dataConstructors = desugaredCtors + , typeSynonyms = desugaredSynonyms } + + modify' $ \checkstate -> checkstate {checkEnv = newEnv} + +desugarConstraintsInDecl :: A.Declaration -> A.Declaration +desugarConstraintsInDecl = \case + A.BindingGroupDeclaration decls -> + A.BindingGroupDeclaration + $ (\(annIdent,nk,expr) -> (annIdent,nk,overTypes desugarConstraintType expr)) <$> decls + A.ValueDecl ann name nk bs [A.MkUnguarded e] -> + A.ValueDecl ann name nk bs [A.MkUnguarded $ overTypes desugarConstraintType e] + A.DataDeclaration ann declTy tName args ctorDecs -> + let fixCtor (A.DataConstructorDeclaration a nm fields) + = A.DataConstructorDeclaration a nm (second (everywhereOnTypes desugarConstraintType) <$> fields) + in A.DataDeclaration ann declTy tName args (fixCtor <$> ctorDecs) + other -> other + +-- Gives much more readable output (with colors for brackets/parens!) than plain old `show` +pTrace :: (Monad m, Show a) => a -> m () +pTrace = traceM . LT.unpack . pShow + +-- | Given a string and a monadic action, produce a trace with the given message before & after the action (with pretty lines to make it more readable) +wrapTrace :: Monad m => String -> m a -> m a +wrapTrace msg act = do + traceM startMsg + res <- act + traceM endMsg + pure res + where + padding = replicate 10 '=' + pad str = padding <> str <> padding + startMsg = pad $ "BEGIN " <> msg + endMsg = pad $ "END " <> msg + +{- + This is used to solve a problem that arises with re-exported instances. + + We diverge from PureScript by "desugaring" constrained types to types that contain + explicit type class dictionaries. (We have to do this for PIR conversion - we have to type + all nodes of the AST.) + + During PureScript's initial desugaring phase, type class declarations, instance declarations, and + expressions that contain type class constaints are transformed into generated value declarations. For example: + + ``` + class Eq a where + eq a :: a -> a -> Bool + + f :: forall a. Eq a => a -> a -> Boolean + f x y = eq x y + ``` + + Is transformed into (something like, I'm ommitting the full generated code for brevity): + + ``` + Eq$Dict :: forall a. {eq :: a -> a -> Boolean } -> {eq :: a -> a -> Boolean} + Eq$Dict x = x + + eq :: forall a. Eq$Dict a -> a -> a -> Boolean + eq = \dict -> case dict of + (v :: {eq :: a -> a -> Boolean}) -> v.eq + + f :: forall a. Eq a => a -> a -> Boolean + f = \dict x y -> (eq dict) x y + ``` + + Three important things to note here: + - PureScript does *not* transform constrained types into types that contain explicit dictionaries, + even though the expressions are desugared to contain those dictionaries. (We do this ourselves + after the PS typechecking phase) + - Generated declarations for type classes and instances are not (and cannot be) exported, + because typeclass desugaring takes place *after* import/export resolution + in their desugaring pipeline. (This would be difficult to fix, each step of the desugaring pipeline + expects input that conforms to the output of the previous step). + - Generated code relating to typeclass dictionaries is ignored by the PureScript typechecker. + Ordinarily, we can rely on the typechecker to insert the type annotation for most + expressions, but we cannot do so here. + + These factors give rise to a problem: Our desugared constraint types (where we transform + type annotations of the form `C a => (..)` into `C$Dict a -> (...)`) no longer contain constraints, + and therefore we cannot use the constraint solving machinery directly to infer the types of + identifiers that refer to type class dictionaries. Because generated type class code cannot be exported + by the user in the source (and would not ordinarily be implicitly re-exported even if it could be exported), + we cannot rely upon normal import resolution to provide the types corresponding to dictionary identifiers. + + This solves the problem. Because we use the same state/module scope as the PS typechecker, we + have access to all of the type class dictionaries (including their identifiers) that are in scope. + When we encounter an identifier that cannot be assigned a type by the normal type lookup process, + we extract a map from identifiers to source types, and lookup the identifier in the map, allowing us to + resolve the types of dictionary expressions. + + These identifiers are always qualified by module in the AST, so cannot clash with local definitions, which + are qualified by SourcePos. + + NOTE: In theory (at least), this component of the type checker environment can change if we + make any calls to `infer` or any of the type checking functions in the + TypeChecker.X namespace. So for now, we rebuild this map every time we fail to + lookup the type for an identifier in the normal way. (Which is grossly + inefficient) + + In principle, we should be able to totally reconstruct the types w/o making + any calls to `infer` or the typechecker machinery. Once that is done, we can + construct this map only once for each module, which will greatly improve performance. +-} +lookupDictType :: M m => Qualified Ident -> m (Maybe SourceType) +lookupDictType nm = do + tyClassDicts <- typeClassDictionaries <$> getEnv + let dictMap = dictionaryIdentMap tyClassDicts + pure $ M.lookup nm dictMap + where + dictionaryIdentMap :: M.Map QualifiedBy (M.Map (Qualified (ProperName 'ClassName)) (M.Map (Qualified Ident) (NEL.NonEmpty NamedDict))) + -> M.Map (Qualified Ident) SourceType + dictionaryIdentMap m = foldl' go M.empty inner + where + -- duplicates? + inner = concatMap NEL.toList . M.elems $ M.unions $ concatMap M.elems $ M.elems m + go :: M.Map (Qualified Ident) SourceType -> NamedDict -> M.Map (Qualified Ident) SourceType + go acc TypeClassDictionaryInScope{..} = M.insert tcdValue dictTy acc + where + dictTy = foldl' srcTypeApp dictTyCon tcdInstanceTypes + dictTyCon = srcTypeConstructor $ coerceProperName . dictTypeName <$> tcdClassName + + +() :: String -> String -> String +x y = x <> "\n" <> y + +-- We need a string for traces and readability is super important here +showIdent' :: Ident -> String +showIdent' = T.unpack . runIdent + +-- | Turns a `Type a` into a `Type ()`. We shouldn't need source position information for types. +-- NOTE: Deprecated (probably) +purusTy :: SourceType -> PurusType +purusTy = id -- fmap (const ()) + +-- | Given a class name, return the TypeClassData associated with the name. +getTypeClassData :: M m => Qualified (ProperName 'ClassName) -> m TypeClassData +getTypeClassData nm = do + env <- getEnv + case M.lookup nm (typeClasses env) of + Nothing -> error $ "No type class data for " show nm " found in" show (typeClasses env) + Just cls -> pure cls + +-- | Given a class name, return the parameters to the class and their *kinds*. (Maybe SourceType is a kind. Type classes cannot be parameterized by anything other than type variables) +getTypeClassArgs :: M m => Qualified (ProperName 'ClassName) -> m [(T.Text,Maybe SourceType)] +getTypeClassArgs nm = getTypeClassData nm >>= (pure . typeClassArguments) + + +-- | Retrieves the current module name from the context. This should never fail (as we set the module name when we start converting a module) +getModuleName :: M m => m ModuleName +getModuleName = gets checkCurrentModule >>= \case + Just mn -> pure mn + Nothing -> error "No module name found in checkState" + +-- Creates a map from a module name to the re-export references defined in +-- that module. +reExportsToCoreFn :: (ModuleName, A.DeclarationRef) -> M.Map ModuleName [Ident] +reExportsToCoreFn (mn', ref') = M.singleton mn' (exportToCoreFn ref') + +toReExportRef :: A.DeclarationRef -> Maybe (ModuleName, A.DeclarationRef) +toReExportRef (A.ReExportRef _ src ref) = + fmap + (, ref) + (A.exportSourceImportedFrom src) +toReExportRef _ = Nothing + +-- Remove duplicate imports +dedupeImports :: [(Ann, ModuleName)] -> [(Ann, ModuleName)] +dedupeImports = fmap swap . M.toList . M.fromListWith const . fmap swap + +-- | Create an Ann (with no comments or metadata) from a SourceSpan +ssA :: SourceSpan -> Ann +ssA ss = (ss, [], Nothing) + +-- Gets metadata for let bindings. +getLetMeta :: A.WhereProvenance -> Maybe Meta +getLetMeta A.FromWhere = Just IsWhere +getLetMeta A.FromLet = Nothing + +-- Gets metadata for values. +getValueMeta :: Environment -> Qualified Ident -> Maybe Meta +getValueMeta env name = + case lookupValue env name of + Just (_, External, _) -> Just IsForeign + _ -> Nothing + +-- Gets metadata for data constructors. +getConstructorMeta :: Environment -> Qualified (ProperName 'ConstructorName) -> Meta +getConstructorMeta env ctor = + case lookupConstructor env ctor of + (Newtype, _, _, _) -> IsNewtype + dc@(Data, _, _, fields) -> + let constructorType = if numConstructors (ctor, dc) == 1 then ProductType else SumType + in IsConstructor constructorType fields + where + + numConstructors + :: (Qualified (ProperName 'ConstructorName), (DataDeclType, ProperName 'TypeName, SourceType, [Ident])) + -> Int + numConstructors ty = length $ filter (((==) `on` typeConstructor) ty) $ M.toList $ dataConstructors env + + typeConstructor + :: (Qualified (ProperName 'ConstructorName), (DataDeclType, ProperName 'TypeName, SourceType, [Ident])) + -> (ModuleName, ProperName 'TypeName) + typeConstructor (Qualified (ByModuleName mn') _, (_, tyCtor, _, _)) = (mn', tyCtor) + typeConstructor _ = internalError "Invalid argument to typeConstructor" + +-- | Find module names from qualified references to values. This is used to +-- ensure instances are imported from any module that is referenced by the +-- current module, not just from those that are imported explicitly (#667). +findQualModules :: [A.Declaration] -> [ModuleName] +findQualModules decls = + let (f, _, _, _, _) = everythingOnValues (++) fqDecls fqValues fqBinders (const []) (const []) + in f `concatMap` decls + +fqDecls :: A.Declaration -> [ModuleName] +fqDecls (A.TypeInstanceDeclaration _ _ _ _ _ _ q _ _) = getQual' q +fqDecls (A.ValueFixityDeclaration _ _ q _) = getQual' q +fqDecls (A.TypeFixityDeclaration _ _ q _) = getQual' q +fqDecls _ = [] + +fqValues :: A.Expr -> [ModuleName] +fqValues (A.Var _ q) = getQual' q +fqValues (A.Constructor _ q) = getQual' q +fqValues _ = [] + +fqBinders :: A.Binder -> [ModuleName] +fqBinders (A.ConstructorBinder _ q _) = getQual' q +fqBinders _ = [] + +getQual' :: Qualified a -> [ModuleName] +getQual' = maybe [] return . getQual + +-- | Converts a ProperName to an Ident. +properToIdent :: ProperName a -> Ident +properToIdent = Ident . runProperName + +-- "Pure" desugaring utils + +-- Desugars case binders from AST to CoreFn representation. Doesn't need to be monadic / essentially the same as the old version. +binderToCoreFn :: Environment -> ModuleName -> SourceSpan -> A.Binder -> Binder Ann +binderToCoreFn env mn _ss (A.LiteralBinder ss lit) = + let lit' = binderToCoreFn env mn ss <$> lit + in LiteralBinder (ss, [], Nothing) lit' +binderToCoreFn _ _ ss A.NullBinder = + NullBinder (ss, [], Nothing) +binderToCoreFn _ _ _ss vb@(A.VarBinder ss name) = trace ("binderToCoreFn: " <> show vb ) $ + VarBinder (ss, [], Nothing) name +binderToCoreFn env mn _ss (A.ConstructorBinder ss dctor@(Qualified mn' _) bs) = + let (_, tctor, _, _) = lookupConstructor env dctor + args = binderToCoreFn env mn _ss <$> bs + in ConstructorBinder (ss, [], Just $ getConstructorMeta env dctor) (Qualified mn' tctor) dctor args +binderToCoreFn env mn _ss (A.NamedBinder ss name b) = + let arg = binderToCoreFn env mn _ss b + in NamedBinder (ss, [], Nothing) name arg +binderToCoreFn env mn _ss (A.PositionedBinder ss _ b) = + binderToCoreFn env mn ss b +binderToCoreFn env mn ss (A.TypedBinder _ b) = + binderToCoreFn env mn ss b +binderToCoreFn _ _ _ A.OpBinder{} = + internalError "OpBinder should have been desugared before binderToCoreFn" +binderToCoreFn _ _ _ A.BinaryNoParensBinder{} = + internalError "BinaryNoParensBinder should have been desugared before binderToCoreFn" +binderToCoreFn _ _ _ A.ParensInBinder{} = + internalError "ParensInBinder should have been desugared before binderToCoreFn" + + + +-- | Desugars import declarations from AST to CoreFn representation. +importToCoreFn :: A.Declaration -> Maybe (Ann, ModuleName) +-- TODO: We probably *DO* want types here +importToCoreFn (A.ImportDeclaration (ss, com) name _ _) = Just ((ss, com, Nothing), name) +importToCoreFn _ = Nothing + +-- | Desugars foreign declarations from AST to CoreFn representation. +externToCoreFn :: A.Declaration -> Maybe Ident +externToCoreFn (A.ExternDeclaration _ name _) = Just name +externToCoreFn _ = Nothing + +-- | Desugars export declarations references from AST to CoreFn representation. +-- CoreFn modules only export values, so all data constructors, instances and +-- values are flattened into one list. +exportToCoreFn :: A.DeclarationRef -> [Ident] +exportToCoreFn (A.TypeRef _ _ (Just dctors)) = fmap properToIdent dctors +exportToCoreFn (A.TypeRef _ _ Nothing) = [] +exportToCoreFn (A.TypeOpRef _ _) = [] +exportToCoreFn (A.ValueRef _ name) = [name] +exportToCoreFn (A.ValueOpRef _ _) = [] +exportToCoreFn (A.TypeClassRef _ _) = [] +exportToCoreFn (A.TypeInstanceRef _ name _) = [name] +exportToCoreFn (A.ModuleRef _ _) = [] +exportToCoreFn (A.ReExportRef _ _ _) = [] diff --git a/src/Language/PureScript/CoreFn/Expr.hs b/src/Language/PureScript/CoreFn/Expr.hs index 20ab33301..ec0fb6e33 100644 --- a/src/Language/PureScript/CoreFn/Expr.hs +++ b/src/Language/PureScript/CoreFn/Expr.hs @@ -1,16 +1,26 @@ --- | --- The core functional representation --- +{-# LANGUAGE TemplateHaskell #-} module Language.PureScript.CoreFn.Expr where - import Prelude import Control.Arrow ((***)) +import GHC.Generics +import Data.Aeson (FromJSON, ToJSON) + + import Language.PureScript.AST.Literals (Literal) import Language.PureScript.CoreFn.Binders (Binder) import Language.PureScript.Names (Ident, ProperName, ProperNameType(..), Qualified) import Language.PureScript.PSString (PSString) +import Language.PureScript.Types (Type (..), SourceType) + +import Control.Lens.TH (makePrisms) +import Control.Lens (Traversal', Lens') +import Data.Text (Text) +import Language.PureScript.Environment +import Data.Bifunctor (Bifunctor(first)) + +type PurusType = SourceType -- Type () -- | -- Data type for expressions and terms @@ -19,23 +29,23 @@ data Expr a -- | -- A literal value -- - = Literal a (Literal (Expr a)) + = Literal a PurusType (Literal (Expr a)) -- | -- A data constructor (type name, constructor name, field names) -- - | Constructor a (ProperName 'TypeName) (ProperName 'ConstructorName) [Ident] + | Constructor a PurusType (ProperName 'TypeName) (ProperName 'ConstructorName) [Ident] -- | -- A record property accessor -- - | Accessor a PSString (Expr a) + | Accessor a PurusType PSString (Expr a) -- | -- Partial record update (original value, fields to copy (if known), fields to update) -- - | ObjectUpdate a (Expr a) (Maybe [PSString]) [(PSString, Expr a)] + | ObjectUpdate a PurusType (Expr a) (Maybe [PSString]) [(PSString, Expr a)] -- | -- Function introduction -- - | Abs a Ident (Expr a) + | Abs a PurusType Ident (Expr a) -- | -- Function application -- @@ -43,16 +53,19 @@ data Expr a -- | -- Variable -- - | Var a (Qualified Ident) + | Var a PurusType (Qualified Ident) -- | -- A case expression -- - | Case a [Expr a] [CaseAlternative a] + | Case a PurusType [Expr a] [CaseAlternative a] -- | -- A let binding -- | Let a [Bind a] (Expr a) - deriving (Eq, Ord, Show, Functor) + deriving (Eq, Ord, Show, Functor, Generic) + +instance FromJSON a => FromJSON (Expr a) +instance ToJSON a => ToJSON (Expr a) -- | -- A let or module binding. @@ -65,7 +78,10 @@ data Bind a -- | -- Mutually recursive binding group for several values -- - | Rec [((a, Ident), Expr a)] deriving (Eq, Ord, Show, Functor) + | Rec [((a, Ident), Expr a)] deriving (Eq, Ord, Show, Functor, Generic) + +instance FromJSON a => FromJSON (Bind a) +instance ToJSON a => ToJSON (Bind a) -- | -- A guard is just a boolean-valued expression that appears alongside a set of binders @@ -84,7 +100,10 @@ data CaseAlternative a = CaseAlternative -- The result expression or a collect of guarded expressions -- , caseAlternativeResult :: Either [(Guard a, Expr a)] (Expr a) - } deriving (Eq, Ord, Show) + } deriving (Eq, Ord, Show, Generic) + +instance FromJSON a => FromJSON (CaseAlternative a) +instance ToJSON a => ToJSON (CaseAlternative a) instance Functor CaseAlternative where @@ -96,14 +115,14 @@ instance Functor CaseAlternative where -- Extract the annotation from a term -- extractAnn :: Expr a -> a -extractAnn (Literal a _) = a -extractAnn (Constructor a _ _ _) = a -extractAnn (Accessor a _ _) = a -extractAnn (ObjectUpdate a _ _ _) = a -extractAnn (Abs a _ _) = a -extractAnn (App a _ _) = a -extractAnn (Var a _) = a -extractAnn (Case a _ _) = a +extractAnn (Literal a _ _) = a +extractAnn (Constructor a _ _ _ _) = a +extractAnn (Accessor a _ _ _) = a +extractAnn (ObjectUpdate a _ _ _ _) = a +extractAnn (Abs a _ _ _) = a +extractAnn (App a _ _) = a +extractAnn (Var a _ _) = a +extractAnn (Case a _ _ _) = a extractAnn (Let a _ _) = a @@ -111,12 +130,15 @@ extractAnn (Let a _ _) = a -- Modify the annotation on a term -- modifyAnn :: (a -> a) -> Expr a -> Expr a -modifyAnn f (Literal a b) = Literal (f a) b -modifyAnn f (Constructor a b c d) = Constructor (f a) b c d -modifyAnn f (Accessor a b c) = Accessor (f a) b c -modifyAnn f (ObjectUpdate a b c d) = ObjectUpdate (f a) b c d -modifyAnn f (Abs a b c) = Abs (f a) b c -modifyAnn f (App a b c) = App (f a) b c -modifyAnn f (Var a b) = Var (f a) b -modifyAnn f (Case a b c) = Case (f a) b c -modifyAnn f (Let a b c) = Let (f a) b c +modifyAnn f (Literal a b c) = Literal (f a) b c +modifyAnn f (Constructor a b c d e) = Constructor (f a) b c d e +modifyAnn f (Accessor a b c d) = Accessor (f a) b c d +modifyAnn f (ObjectUpdate a b c d e) = ObjectUpdate (f a) b c d e +modifyAnn f (Abs a b c d) = Abs (f a) b c d +modifyAnn f (App a b c) = App (f a) b c +modifyAnn f (Var a b c) = Var (f a) b c +modifyAnn f (Case a b c d) = Case (f a) b c d +modifyAnn f (Let a b c) = Let (f a) b c + +makePrisms ''Expr +makePrisms ''Bind diff --git a/src/Language/PureScript/CoreFn/FromJSON.hs b/src/Language/PureScript/CoreFn/FromJSON.hs index d0426b6f8..b77a49726 100644 --- a/src/Language/PureScript/CoreFn/FromJSON.hs +++ b/src/Language/PureScript/CoreFn/FromJSON.hs @@ -26,8 +26,14 @@ import Language.PureScript.CoreFn (Bind(..), Binder(..), CaseAlternative(..), Co import Language.PureScript.Names (Ident(..), ModuleName(..), ProperName(..), Qualified(..), QualifiedBy(..), unusedIdent) import Language.PureScript.PSString (PSString) +import Language.PureScript.Types () + import Text.ParserCombinators.ReadP (readP_to_S) +-- dunno how to work around the orphan +instance FromJSON (Module (Bind Ann) Ann) where + parseJSON = fmap snd . moduleFromJSON + parseVersion' :: String -> Maybe Version parseVersion' str = case filter (null . snd) $ readP_to_S parseVersion str of @@ -127,7 +133,7 @@ qualifiedFromJSON f = withObject "Qualified" qualifiedFromObj moduleNameFromJSON :: Value -> Parser ModuleName moduleNameFromJSON v = ModuleName . T.intercalate "." <$> listParser parseJSON v -moduleFromJSON :: Value -> Parser (Version, Module Ann) +moduleFromJSON :: Value -> Parser (Version, Module (Bind Ann) Ann) moduleFromJSON = withObject "Module" moduleFromObj where moduleFromObj o = do @@ -141,6 +147,7 @@ moduleFromJSON = withObject "Module" moduleFromObj moduleDecls <- o .: "decls" >>= listParser (bindFromJSON modulePath) moduleForeign <- o .: "foreign" >>= listParser identFromJSON moduleComments <- o .: "comments" >>= listParser parseJSON + moduleDataTypes <- o .: "dataTypes" >>= parseJSON return (version, Module {..}) versionFromJSON :: String -> Parser Version @@ -189,8 +196,8 @@ exprFromJSON :: FilePath -> Value -> Parser (Expr Ann) exprFromJSON modulePath = withObject "Expr" exprFromObj where exprFromObj o = do - type_ <- o .: "type" - case type_ of + kind_ <- o .: "kind" + case kind_ of "Var" -> varFromObj o "Literal" -> literalExprFromObj o "Constructor" -> constructorFromObj o @@ -200,43 +207,51 @@ exprFromJSON modulePath = withObject "Expr" exprFromObj "App" -> appFromObj o "Case" -> caseFromObj o "Let" -> letFromObj o - _ -> fail ("not recognized expression type: \"" ++ T.unpack type_ ++ "\"") + _ -> fail ("not recognized expression kind: \"" ++ T.unpack kind_ ++ "\"") + + tyFromObj o = o .: "type" >>= parseJSON varFromObj o = do ann <- o .: "annotation" >>= annFromJSON modulePath + ty <- tyFromObj o qi <- o .: "value" >>= qualifiedFromJSON Ident - return $ Var ann qi + return $ Var ann ty qi literalExprFromObj o = do ann <- o .: "annotation" >>= annFromJSON modulePath + ty <- tyFromObj o lit <- o .: "value" >>= literalFromJSON (exprFromJSON modulePath) - return $ Literal ann lit + return $ Literal ann ty lit constructorFromObj o = do ann <- o .: "annotation" >>= annFromJSON modulePath tyn <- o .: "typeName" >>= properNameFromJSON + ty <- tyFromObj o con <- o .: "constructorName" >>= properNameFromJSON is <- o .: "fieldNames" >>= listParser identFromJSON - return $ Constructor ann tyn con is + return $ Constructor ann ty tyn con is accessorFromObj o = do ann <- o .: "annotation" >>= annFromJSON modulePath + ty <- tyFromObj o f <- o .: "fieldName" e <- o .: "expression" >>= exprFromJSON modulePath - return $ Accessor ann f e + return $ Accessor ann ty f e objectUpdateFromObj o = do ann <- o .: "annotation" >>= annFromJSON modulePath + ty <- tyFromObj o e <- o .: "expression" >>= exprFromJSON modulePath copy <- o .: "copy" >>= parseJSON us <- o .: "updates" >>= recordFromJSON (exprFromJSON modulePath) - return $ ObjectUpdate ann e copy us + return $ ObjectUpdate ann ty e copy us absFromObj o = do ann <- o .: "annotation" >>= annFromJSON modulePath + ty <- tyFromObj o idn <- o .: "argument" >>= identFromJSON e <- o .: "body" >>= exprFromJSON modulePath - return $ Abs ann idn e + return $ Abs ann ty idn e appFromObj o = do ann <- o .: "annotation" >>= annFromJSON modulePath @@ -246,9 +261,10 @@ exprFromJSON modulePath = withObject "Expr" exprFromObj caseFromObj o = do ann <- o .: "annotation" >>= annFromJSON modulePath + ty <- tyFromObj o cs <- o .: "caseExpressions" >>= listParser (exprFromJSON modulePath) cas <- o .: "caseAlternatives" >>= listParser (caseAlternativeFromJSON modulePath) - return $ Case ann cs cas + return $ Case ann ty cs cas letFromObj o = do ann <- o .: "annotation" >>= annFromJSON modulePath diff --git a/src/Language/PureScript/CoreFn/Laziness.hs b/src/Language/PureScript/CoreFn/Laziness.hs deleted file mode 100644 index 9941fd41c..000000000 --- a/src/Language/PureScript/CoreFn/Laziness.hs +++ /dev/null @@ -1,568 +0,0 @@ -module Language.PureScript.CoreFn.Laziness - ( applyLazinessTransform - ) where - -import Protolude hiding (force) -import Protolude.Unsafe (unsafeHead) - -import Control.Arrow ((&&&)) -import Data.Array qualified as A -import Data.Coerce (coerce) -import Data.Graph (SCC(..), stronglyConnComp) -import Data.List (foldl1', (!!)) -import Data.IntMap.Monoidal qualified as IM -import Data.IntSet qualified as IS -import Data.Map.Monoidal qualified as M -import Data.Semigroup (Max(..)) -import Data.Set qualified as S - -import Language.PureScript.AST.SourcePos (SourcePos(..), SourceSpan(..), nullSourceSpan) -import Language.PureScript.Constants.Libs qualified as C -import Language.PureScript.CoreFn (Ann, Bind, Expr(..), Literal(..), Meta(..), ssAnn, traverseCoreFn) -import Language.PureScript.Crash (internalError) -import Language.PureScript.Names (pattern ByNullSourcePos, Ident(..), InternalIdentData(..), ModuleName, Qualified(..), QualifiedBy(..), runIdent, runModuleName, toMaybeModuleName) -import Language.PureScript.PSString (mkString) - --- This module is responsible for ensuring that the bindings in recursive --- binding groups are initialized in a valid order, introducing run-time --- laziness and initialization checks as necessary. --- --- PureScript is a call-by-value language with strict data constructors, this --- transformation notwithstanding. The only laziness introduced here is in the --- initialization of a binding. PureScript is uninterested in the order in --- which bindings are written by the user. The compiler has always attempted to --- emit the bindings in an order that makes sense for the backend, but without --- this transformation, recursive bindings are emitted in an arbitrary order, --- which can cause unexpected behavior at run time if a binding is dereferenced --- before it has initialized. --- --- To prevent unexpected errors, this transformation does a syntax-driven --- analysis of a single recursive binding group to attempt to statically order --- the bindings, and when that fails, falls back to lazy initializers that will --- succeed or fail deterministically with a clear error at run time. --- --- Example: --- --- x = f \_ -> --- x --- --- becomes (with some details of the $runtime_lazy function elided): --- --- -- the binding of x has been rewritten as a lazy initializer --- $lazy_x = $runtime_lazy \_ -> --- f \_ -> --- $lazy_x 2 -- the reference to x has been rewritten as a force call --- x = $lazy_x 1 --- --- Central to this analysis are the concepts of delay and force, which are --- attributes given to every subexpression in the binding group. Delay and --- force are defined by the following traversal. This traversal is used twice: --- once to collect all the references made by each binding in the group, and --- then again to rewrite some references to force calls. (The implications of --- delay and force on initialization order are specified later.) - --- | --- Visits every `Var` in an expression with the provided function, including --- the amount of delay and force applied to that `Var`, and substitutes the --- result back into the tree (propagating an `Applicative` effect). --- --- Delay is a non-negative integer that represents the number of lambdas that --- enclose an expression. Force is a non-negative integer that represents the --- number of values that are being applied to an expression. Delay is always --- statically determinable, but force can be *unknown*, so it's represented --- here with a Maybe. In a function application `f a b`, `f` has force 2, but --- `a` and `b` have unknown force--it depends on what `f` does with them. --- --- The rules of assigning delay and force are simple: --- * The expressions that are assigned to bindings in this group have --- delay 0, force 0. --- * In a function application, the function expression has force 1 higher --- than the force of the application expression, and the argument --- expression has unknown force. --- * UNLESS this argument is being directly provided to a constructor (in --- other words, the function expression is either a constructor itself or --- a constructor that has already been partially applied), in which case --- the force of both subexpressions is unchanged. We can assume that --- constructors don't apply any additional force to their arguments. --- * If the force of a lambda is zero, the delay of the body of the lambda is --- incremented; otherwise, the force of the body of the lambda is --- decremented. (Applying one argument to a lambda cancels out one unit of --- delay.) --- * In the argument of a Case and the bindings of a Let, force is unknown. --- * Everywhere else, preserve the delay and force of the enclosing --- expression. --- --- Here are some illustrative examples of the above rules. We will use a --- pseudocode syntax to annotate a subexpression with delay and force: --- `expr#d!f` means `expr` has delay d and force f. `!*` is used to denote --- unknown force. --- --- x = y#0!0 --- x = y#0!2 a#0!* b#0!* --- x = (\_ -> y#1!0)#0!0 --- x = \_ _ -> y#2!1 a#2!* --- x = (\_ -> y#0!0)#0!1 z#0!* --- x = Just { a: a#0!0, b: b#0!0 } --- x = let foo = (y#1!* a b#1!*)#1!* in foo + 1 --- --- (Note that this analysis is quite ignorant of any actual control flow --- choices made at run time. It doesn't even track what happens to a reference --- after it has been locally bound by a Let or Case. Instead, it just assumes --- the worst--once locally bound to a new name, it imagines that absolutely --- anything could happen to that new name and thus to the underlying reference. --- But the value-to-weight ratio of this approach is perhaps surprisingly --- high.) --- --- Every subexpression gets a delay and a force, but we are only interested --- in references to other bindings in the binding group, so the traversal only --- exposes `Var`s to the provided function. --- -onVarsWithDelayAndForce :: forall f. Applicative f => (Int -> Maybe Int -> Ann -> Qualified Ident -> f (Expr Ann)) -> Expr Ann -> f (Expr Ann) -onVarsWithDelayAndForce f = snd . go 0 $ Just 0 - where - go :: Int -> Maybe Int -> (Bind Ann -> f (Bind Ann), Expr Ann -> f (Expr Ann)) - go delay force = (handleBind, handleExpr') - where - (handleBind, handleExpr, handleBinder, handleCaseAlternative) = traverseCoreFn handleBind handleExpr' handleBinder handleCaseAlternative - handleExpr' = \case - Var a i -> f delay force a i - Abs a i e -> Abs a i <$> snd (if force == Just 0 then go (succ delay) force else go delay $ fmap pred force) e - -- A clumsy hack to preserve TCO in a particular idiom of unsafePartial once seen in Data.Map.Internal, possibly still used elsewhere. - App a1 e1@(Var _ C.I_unsafePartial) (Abs a2 i e2) -> App a1 e1 . Abs a2 i <$> handleExpr' e2 - App a e1 e2 -> - -- `handleApp` is just to handle the constructor application exception - -- somewhat gracefully (i.e., without requiring a deep inspection of - -- the function expression at every step). If we didn't care about - -- constructors, this could have been simply: - -- App a <$> snd (go delay (fmap succ force)) e1 <*> snd (go delay Nothing) e2 - handleApp 1 [(a, e2)] e1 - Case a vs alts -> Case a <$> traverse (snd $ go delay Nothing) vs <*> traverse handleCaseAlternative alts - Let a ds e -> Let a <$> traverse (fst $ go delay Nothing) ds <*> handleExpr' e - other -> handleExpr other - - handleApp len args = \case - App a e1 e2 -> handleApp (len + 1) ((a, e2) : args) e1 - Var a@(_, _, Just meta) i | isConstructorLike meta - -> foldl (\e1 (a2, e2) -> App a2 <$> e1 <*> handleExpr' e2) (f delay force a i) args - e -> foldl (\e1 (a2, e2) -> App a2 <$> e1 <*> snd (go delay Nothing) e2) (snd (go delay (fmap (+ len) force)) e) args - isConstructorLike = \case - IsConstructor{} -> True - IsNewtype -> True - _ -> False - --- Once we assign a delay and force value to every `Var` in the binding group, --- we can consider how to order the bindings to allow them all to successfully --- initialize. There is one principle here: each binding must be initialized --- before the identifier being bound is ready for use. If the preorder thus --- induced has cycles, those cycles need to be resolved with laziness. All of --- the details concern what "ready for use" means. --- --- The definition of delay and force suggests that "ready for use" depends on --- those attributes. If a lambda is bound to the name x, then the references in --- the lambda don't need to be initialized before x is initialized. This is --- represented by the fact that those references have non-zero delay. But if --- the expression bound to x is instead the application of a function y that is --- also bound in this binding group, then not only does y need to be --- initialized before x, so do some of the non-zero delay references in y. This --- is represented by the fact that the occurrence of y in the expression bound --- to x has non-zero force. --- --- An example, reusing the pseudocode annotations defined above: --- --- x _ = y#1!0 --- y = x#0!1 a --- --- y doesn't need to be initialized before x is, because the reference to y in --- x's initializer has delay 1. But y does need to be initialized before x is --- ready for use with force 1, because force 1 is enough to overcome the delay --- of that reference. And since y has a delay-0 reference to x with force 1, y --- will need to be ready for use before it is initialized; thus, y needs to be --- made lazy. --- --- So just as function applications "cancel out" lambdas, a known applied force --- cancels out an equal amount of delay, causing some references that may not --- have been needed earlier to enter play. (And to be safe, we must assume that --- unknown force cancels out *any* amount of delay.) There is another, subtler --- aspect of this: if there are not enough lambdas to absorb every argument --- applied to a function, those arguments will end up applied to the result of --- the function. Likewise, if there is excess force left over after some of it --- has been canceled by delay, that excess is carried to the references --- activated. (Again, an unknown amount of force must be assumed to lead to an --- unknown amount of excess force.) --- --- Another example: --- --- f = g#0!2 a b --- g x = h#1!2 c x --- h _ _ _ = f#3!0 --- --- Initializing f will lead to an infinite loop in this example. f invokes g --- with two arguments. g absorbs one argument, and the second ends up being --- applied to the result of h c x, resulting in h being invoked with three --- arguments. Invoking h with three arguments results in dereferencing f, which --- is not yet ready. To capture this loop in our analysis, we say that making --- f ready for use with force 0 requires making g ready for use with force 2, --- which requires making h ready for use with force 3 (two units of force from --- the lexical position of h, plus one unit of excess force carried forward), --- which cyclically requires f to be ready for use with force 0. --- --- These preceding observations are captured and generalized by the following --- rules: --- --- USE-INIT: Before a reference to x is ready for use with any force, x must --- be initialized. --- --- We will make x lazy iff this rule induces a cycle--i.e., initializing x --- requires x to be ready for use first. --- --- USE-USE: Before a reference to x is ready for use with force f: --- * if a reference in the initializer of x has delay d and force f', --- * and either d <= f or f is unknown, --- * then that reference must itself be ready for use with --- force f – d + f' (or with unknown force if f or f' is unknown). --- --- USE-IMMEDIATE: Initializing a binding x is equivalent to requiring a --- reference to x to be ready for use with force 0, per USE-USE. --- --- Equivalently: before x is initialized, any reference in the initializer --- of x with delay 0 and force f must be ready for use with force f. --- --- Examples: --- --- Assume x is bound in a recursive binding group with the below bindings. --- --- All of the following initializers require x to be ready for use with some --- amount of force, and therefore require x to be initialized first. --- --- a = x#0!0 --- b = (\_ -> x#0!0) 1 --- c = foo x#0!* --- d = (\_ -> foo x#0!*) 1 --- --- In the following initializers, before p can be initialized, x must be --- ready for use with force f – d + f'. (And both x and q must be --- initialized, of course; but x being ready for use with that force may --- induce additional constraints.) --- --- p = ... q#0!f ... --- q = ... x#d!f' ... (where d <= f) --- --- Excess force stacks, of course: in the following initializers, before r --- can be initialized, x must be ready for use with force --- f — d + f' — d' + f'': --- --- r = ... s#0!f ... --- s = ... t#d!f' ... (where d <= f) --- t = ... x#d'!f'' ... (where d' <= f – d + f') --- --- --- To satisfy these rules, we will construct a graph between (identifier, --- delay) pairs, with edges induced by the USE-USE rule, and effectively run a --- topsort to get the initialization preorder. For this part, it's simplest to --- think of delay as an element of the naturals extended with a positive --- infinity, corresponding to an unknown amount of force. (We'll do arithmetic --- on these extended naturals as you would naively expect; we won't do anything --- suspect like subtracting infinity from infinity.) With that in mind, we can --- construct the graph as follows: for each reference from i1 to i2 with delay --- d and force f, draw an infinite family of edges from (i1, d + n) to (i2, f + --- n) for all 0 <= n <= ∞, where n represents the excess force carried over --- from a previous edge. Unfortunately, as an infinite graph, we can't expect --- the tools in Data.Graph to help us traverse it; we will have to be a little --- bit clever. --- --- The following data types and functions are for searching this infinite graph --- and carving from it a finite amount of data to work with. Specifically, we --- want to know for each identifier i, which other identifiers are --- irreflexively reachable from (i, 0) (and thus must be initialized before i --- is), and with what maximum force (in the event of a loop, not every --- reference to i in the reachable identifier needs to be rewritten to a force --- call; only the ones with delay up to the maximum force used during i's --- initialization). We also want the option of aborting a given reachability --- search, for one of two reasons. --- --- * If we encounter a reference with unknown force, abort. --- * If we encounter a cycle where force on a single identifier is --- increasing, abort. (Because of USE-USE, as soon as an identifier is --- revisited with greater force than its first visit, the difference is --- carried forward as excess, so it is possible to retrace that path to get --- an arbitrarily high amount of force.) --- --- Both reasons mean that it is theoretically possible for the identifier in --- question to need every other identifier in the binding group to be --- initialized before it is. (Every identifier in a recursive binding group is --- necessarily reachable from every other, ignoring delay and force, which is --- what arbitrarily high force lets you do.) --- --- In order to reuse parts of this reachability computation across identifiers, --- we are going to represent it with a rose tree data structure interleaved with --- a monad capturing the abort semantics. (The monad is Maybe, but we don't --- need to know that here!) - -type MaxRoseTree m a = m (IM.MonoidalIntMap (MaxRoseNode m a)) -data MaxRoseNode m a = MaxRoseNode a (MaxRoseTree m a) - --- Dissecting this data structure: --- --- m (...) --- ^ represents whether to abort or continue the search --- --- IM.MonoidalIntMap (...) --- ^ the keys of this map are other identifiers reachable from the current --- one (we'll map the identifiers in this binding group to Ints for ease of --- computation) --- --- the values of this map are: --- --- MaxRoseNode a (...) --- ^ this will store the force applied to the next identifier --- (MaxRoseTree m a) --- ^ and this, the tree of identifiers reachable from there --- --- We're only interested in continuing down the search path that applies the --- most force to a given identifier! So when we combine two MaxRoseTrees, --- we want to resolve any key collisions in their MonoidalIntMaps with this --- semigroup: - -instance Ord a => Semigroup (MaxRoseNode m a) where - l@(MaxRoseNode l1 _) <> r@(MaxRoseNode r1 _) = if r1 > l1 then r else l - --- And that's why this is called a MaxRoseTree. --- --- Traversing this tree to get a single MonoidalIntMap with the entire closure --- plus force information is fairly straightforward: - -mrtFlatten :: (Monad m, Ord a) => MaxRoseTree m a -> m (IM.MonoidalIntMap (Max a)) -mrtFlatten = (getAp . IM.foldMapWithKey (\i (MaxRoseNode a inner) -> Ap $ (IM.singleton i (Max a) <>) <$> mrtFlatten inner) =<<) - --- The use of the `Ap` monoid ensures that if any child of this tree aborts, --- the entire tree aborts. --- --- One might ask, why interleave the abort monad with the tree at all if we're --- just going to flatten it out at the end? The point is to flatten it out at --- the end, but *not* during the generation of the tree. Attempting to flatten --- the tree as we generate it can result in an infinite loop, because a subtree --- needs to be exhaustively searched for abort conditions before it can be used --- in another tree. With this approach, we can use lazy trees as building --- blocks and, as long as they get rewritten to be finite or have aborts before --- they're flattened, the analysis still terminates. - --- | --- Given a maximum index and a function that returns a map of edges to next --- indices, returns an array for each index up to maxIndex of maps from the --- indices reachable from the current index, to the maximum force applied to --- those indices. -searchReachable - :: forall m force - . (Alternative m, Monad m, Enum force, Ord force) - => Int - -> ((Int, force) -> m (IM.MonoidalIntMap (Max force))) - -> A.Array Int (m (IM.MonoidalIntMap (Max force))) -searchReachable maxIdx lookupEdges = mrtFlatten . unsafeHead <$> mem - where - -- This is a finite array of infinite lists, used to memoize all the search - -- trees. `unsafeHead` is used above to pull the first tree out of each list - -- in the array--the one corresponding to zero force, which is what's needed - -- to initialize the corresponding identifier. (`unsafeHead` is safe here, of - -- course: infinite lists.) - mem :: A.Array Int [MaxRoseTree m force] - mem = A.listArray (0, maxIdx) - [ [cutLoops <*> fmap (IM.mapWithKey memoizedNode) . lookupEdges $ (i, f) | f <- [toEnum 0..]] - | i <- [0..maxIdx] - ] - - memoizedNode :: Int -> Max force -> MaxRoseNode m force - memoizedNode i (Max force) = MaxRoseNode force $ mem A.! i !! fromEnum force - - -- And this is the function that prevents the search from actually being - -- infinite. It applies a filter to a `MaxRoseTree` at every level, looking for - -- indices anywhere in the tree that match the current vertex. If a match is - -- found with greater force than the current force, that part of the tree is - -- rewritten to abort; otherwise, that part of the tree is rewritten to be - -- empty (there's nothing new in that part of the search). - -- - -- A new version of `cutLoops` is applied for each node in the search, so - -- each edge in a search path will add another filter on a new index. Since - -- there are a finite number of indices in our universe, this guarantees that - -- the analysis terminates, because no single search path can have length - -- greater than `maxIdx`. - cutLoops :: (Int, force) -> MaxRoseTree m force -> MaxRoseTree m force - cutLoops (i, force) = go - where - go = (=<<) . IM.traverseWithKey $ \i' (MaxRoseNode force' inner) -> - MaxRoseNode force' <$> if i == i' then guard (force >= force') $> pure IM.empty else pure $ go inner - --- One last data structure to define and then it's on to the main event. --- --- The laziness transform effectively takes a list of eager bindings (x = ...) --- and splits some of them into lazy definitions ($lazy_x = ...) and lazy --- bindings (x = $lazy_x ...). It's convenient to work with these three --- declarations as the following sum type: - -data RecursiveGroupItem e = EagerBinding Ann e | LazyDefinition e | LazyBinding Ann - deriving Functor - --- | --- Transform a recursive binding group, reordering the bindings within when a --- correct initialization order can be statically determined, and rewriting --- bindings and references to be lazy otherwise. --- -applyLazinessTransform :: ModuleName -> [((Ann, Ident), Expr Ann)] -> ([((Ann, Ident), Expr Ann)], Any) -applyLazinessTransform mn rawItems = let - - -- Establish the mapping from names to ints. - rawItemsByName :: M.MonoidalMap Ident (Ann, Expr Ann) - rawItemsByName = M.fromList $ (snd . fst &&& first fst) <$> rawItems - - maxIdx = M.size rawItemsByName - 1 - - rawItemsByIndex :: A.Array Int (Ann, Expr Ann) - rawItemsByIndex = A.listArray (0, maxIdx) $ M.elems rawItemsByName - - names :: S.Set Ident - names = M.keysSet rawItemsByName - - -- Now do the first delay/force traversal of all the bindings to find - -- references to other names in this binding group. - -- - -- The parts of this type mean: - -- D is the maximum force (or Nothing if unknown) with which the identifier C - -- is referenced in any delay-B position inside the expression A. - -- - -- where A, B, C, and D are as below: - -- A B (keys) C (keys) D - findReferences :: Expr Ann -> IM.MonoidalIntMap (IM.MonoidalIntMap (Ap Maybe (Max Int))) - findReferences = (getConst .) . onVarsWithDelayAndForce $ \delay force _ -> \case - Qualified qb ident | all (== mn) (toMaybeModuleName qb), Just i <- ident `S.lookupIndex` names - -> Const . IM.singleton delay . IM.singleton i $ coerceForce force - _ -> Const IM.empty - - -- The parts of this type mean: - -- D is the maximum force (or Nothing if unknown) with which the identifier C - -- is referenced in any delay-B position inside the binding of identifier A. - -- - -- where A, B, C, and D are as below: - -- A B (keys) C (keys) D - refsByIndex :: A.Array Int (IM.MonoidalIntMap (IM.MonoidalIntMap (Ap Maybe (Max Int)))) - refsByIndex = findReferences . snd <$> rawItemsByIndex - - -- Using the approach explained above, traverse the reference graph generated - -- by `refsByIndex` and find all reachable names. - -- - -- The parts of this type mean: - -- D is the maximum force with which the identifier C is referenced, - -- directly or indirectly, during the initialization of identifier A. B is - -- Nothing if the analysis of A was inconclusive and A might need the entire - -- binding group. - -- - -- where A, B, C, and D are as below: - -- A B C (keys) D - reachablesByIndex :: A.Array Int (Maybe (IM.MonoidalIntMap (Max Int))) - reachablesByIndex = searchReachable maxIdx $ \(i, force) -> - getAp . flip IM.foldMapWithKey (dropKeysAbove force $ refsByIndex A.! i) $ \delay -> - IM.foldMapWithKey $ \i' force' -> - Ap $ IM.singleton i' . Max . (force - delay +) <$> uncoerceForce force' - - -- If `reachablesByIndex` is a sort of labeled relation, this function - -- produces part of the reverse relation, but only for the edges from the - -- given vertex. - -- - -- The parts of this type mean: - -- The identifier A is reachable from the identifier B with maximum force C - -- (B is also the index provided to the function). - -- - -- where A, B, and C are as below: - -- (B) A B (singleton key) C - reverseReachablesFor :: Int -> IM.MonoidalIntMap (IM.MonoidalIntMap (Ap Maybe (Max Int))) - reverseReachablesFor i = case reachablesByIndex A.! i of - Nothing -> IM.fromAscList $ (, IM.singleton i $ Ap Nothing) <$> [0..maxIdx] - Just im -> IM.singleton i . Ap . Just <$> im - - -- We can use `reachablesByIndex` to build a finite graph and topsort it; - -- in the process, we'll pack the nodes of the graph with data we'll want - -- next. Remember that if our reachability computation aborted, we have to - -- assume that every other identifier is reachable from that one--hence the - -- `maybe [0..maxIdx]`. - sccs = stronglyConnComp $ do - (i, mbReachable) <- A.assocs reachablesByIndex - pure ((reverseReachablesFor i, (S.elemAt i names, rawItemsByIndex A.! i)), i, maybe [0..maxIdx] (IS.toList . IM.keysSet) mbReachable) - - (replacements, items) = flip foldMap sccs $ \case - -- The easy case: this binding doesn't need to be made lazy after all! - AcyclicSCC (_, (ident, (a, e))) -> pure [(ident, EagerBinding a e)] - -- The tough case: we have a loop. - -- We need to do two things here: - -- * Collect the reversed reachables relation for each vertex in this - -- loop; we'll use this to replace references with force calls - -- * Copy the vertex list into two lists: a list of lazy definitions and - -- a list of lazy bindings - -- Both of these results are monoidal, so the outer `foldMap` will - -- concatenate them pairwise. - CyclicSCC vertices -> (foldMap fst vertices, map (fmap (LazyDefinition . snd) . snd) vertices ++ map (fmap (LazyBinding . fst) . snd) vertices) - - -- We have `replacements` expressed in terms of indices; we want to map it - -- back to names before traversing the bindings again. - replacementsByName :: M.MonoidalMap Ident (M.MonoidalMap Ident (Ap Maybe (Max Int))) - replacementsByName = M.fromAscList . map (bimap (flip S.elemAt names) (M.fromAscList . map (first (flip S.elemAt names)) . IM.toAscList)) . IM.toAscList $ replacements - - -- And finally, this is the second delay/force traversal where we take - -- `replacementsByName` and use it to rewrite references with force calls, - -- but only if the delay of those references is at most the maximum amount - -- of force used by the initialization of the referenced binding to - -- reference the outer binding. A reference made with a higher delay than - -- that can safely continue to use the original reference, since it won't be - -- needed until after the referenced binding is done initializing. - replaceReferencesWithForceCall :: (Ident, RecursiveGroupItem (Expr Ann)) -> (Ident, RecursiveGroupItem (Expr Ann)) - replaceReferencesWithForceCall pair@(ident, item) = case ident `M.lookup` replacementsByName of - Nothing -> pair - Just m -> let - rewriteExpr = (runIdentity .) . onVarsWithDelayAndForce $ \delay _ ann -> pure . \case - Qualified qb ident' | all (== mn) (toMaybeModuleName qb), any (all (>= Max delay) . getAp) $ ident' `M.lookup` m - -> makeForceCall ann ident' - q -> Var ann q - in (ident, rewriteExpr <$> item) - - -- All that's left to do is run the above replacement on every item, - -- translate items from our `RecursiveGroupItem` representation back into the - -- form CoreFn expects, and inform the caller whether we made any laziness - -- transformations after all. (That last bit of information is used to - -- determine if the runtime factory function needs to be injected.) - in (uncurry fromRGI . replaceReferencesWithForceCall <$> items, Any . not $ IM.null replacements) - - where - - nullAnn = ssAnn nullSourceSpan - runtimeLazy = Var nullAnn . Qualified ByNullSourcePos $ InternalIdent RuntimeLazyFactory - runFn3 = Var nullAnn . Qualified (ByModuleName C.M_Data_Function_Uncurried) . Ident $ C.S_runFn <> "3" - strLit = Literal nullAnn . StringLiteral . mkString - - lazifyIdent = \case - Ident txt -> InternalIdent $ Lazy txt - _ -> internalError "Unexpected argument to lazifyIdent" - - makeForceCall :: Ann -> Ident -> Expr Ann - makeForceCall (ss, _, _) ident - -- We expect the functions produced by `runtimeLazy` to accept one - -- argument: the line number on which this reference is made. The runtime - -- code uses this number to generate a message that identifies where the - -- evaluation looped. - = App nullAnn (Var nullAnn . Qualified ByNullSourcePos $ lazifyIdent ident) - . Literal nullAnn . NumericLiteral . Left . toInteger . sourcePosLine - $ spanStart ss - - fromRGI :: Ident -> RecursiveGroupItem (Expr Ann) -> ((Ann, Ident), Expr Ann) - fromRGI i = \case - EagerBinding a e -> ((a, i), e) - -- We expect the `runtimeLazy` factory to accept three arguments: the - -- identifier being initialized, the name of the module, and of course a - -- thunk that actually contains the initialization code. - LazyDefinition e -> ((nullAnn, lazifyIdent i), foldl1' (App nullAnn) [runFn3, runtimeLazy, strLit $ runIdent i, strLit $ runModuleName mn, Abs nullAnn UnusedIdent e]) - LazyBinding a -> ((a, i), makeForceCall a i) - - dropKeysAbove :: Int -> IM.MonoidalIntMap a -> IM.MonoidalIntMap a - dropKeysAbove n = fst . IM.split (n + 1) - - coerceForce :: Maybe Int -> Ap Maybe (Max Int) - coerceForce = coerce - - uncoerceForce :: Ap Maybe (Max Int) -> Maybe Int - uncoerceForce = coerce diff --git a/src/Language/PureScript/CoreFn/Module.hs b/src/Language/PureScript/CoreFn/Module.hs index 09f5189c4..481c7c862 100644 --- a/src/Language/PureScript/CoreFn/Module.hs +++ b/src/Language/PureScript/CoreFn/Module.hs @@ -1,18 +1,31 @@ +{-# LANGUAGE StandaloneDeriving, ScopedTypeVariables, StrictData #-} +{-# LANGUAGE StandaloneKindSignatures #-} module Language.PureScript.CoreFn.Module where import Prelude import Data.Map.Strict (Map) +import Data.List (sort) +import Data.Text (Text) import Language.PureScript.AST.SourcePos (SourceSpan) +import Language.PureScript.AST.Literals (Literal(..)) import Language.PureScript.Comments (Comment) -import Language.PureScript.CoreFn.Expr (Bind) -import Language.PureScript.Names (Ident, ModuleName) +import Language.PureScript.CoreFn.Expr (Bind(..), Expr(..), CaseAlternative) +import Language.PureScript.CoreFn.Ann +import Language.PureScript.Names (Ident, ModuleName, ProperNameType (..), ProperName) +import Data.Bifunctor (second) +import Language.PureScript.AST.Declarations (DataConstructorDeclaration) +import Language.PureScript.Environment (DataDeclType) +import Language.PureScript.Types (SourceType) + +import Data.Kind qualified as GHC -- | -- The CoreFn module representation -- -data Module a = Module +type Module :: GHC.Type -> GHC.Type -> GHC.Type +data Module decl a = Module { moduleSourceSpan :: SourceSpan , moduleComments :: [Comment] , moduleName :: ModuleName @@ -21,5 +34,9 @@ data Module a = Module , moduleExports :: [Ident] , moduleReExports :: Map ModuleName [Ident] , moduleForeign :: [Ident] - , moduleDecls :: [Bind a] + , moduleDecls :: [decl] + , moduleDataTypes :: Map (ProperName 'TypeName) (DataDeclType,[(Text, Maybe SourceType)],[DataConstructorDeclaration]) } deriving (Functor, Show) + +deriving instance Eq a => Eq (Module (Bind a) a) + diff --git a/src/Language/PureScript/CoreFn/Optimizer.hs b/src/Language/PureScript/CoreFn/Optimizer.hs index 722893c43..7efeb58ec 100644 --- a/src/Language/PureScript/CoreFn/Optimizer.hs +++ b/src/Language/PureScript/CoreFn/Optimizer.hs @@ -13,7 +13,7 @@ import Language.PureScript.Constants.Libs qualified as C -- | -- CoreFn optimization pass. -- -optimizeCoreFn :: Module Ann -> Supply (Module Ann) +optimizeCoreFn :: Module (Bind Ann) Ann -> Supply (Module (Bind Ann) Ann) optimizeCoreFn m = fmap (\md -> m {moduleDecls = md}) . optimizeCommonSubexpressions (moduleName m) . optimizeModuleDecls $ moduleDecls m optimizeModuleDecls :: [Bind Ann] -> [Bind Ann] @@ -25,7 +25,7 @@ optimizeModuleDecls = map transformBinds optimizeDataFunctionApply :: Expr a -> Expr a optimizeDataFunctionApply e = case e of - (App a (App _ (Var _ fn) x) y) + (App a (App _ (Var _ t3 fn) x) y) | C.I_functionApply <- fn -> App a x y | C.I_functionApplyFlipped <- fn -> App a y x _ -> e diff --git a/src/Language/PureScript/CoreFn/Pretty.hs b/src/Language/PureScript/CoreFn/Pretty.hs new file mode 100644 index 000000000..7a4516059 --- /dev/null +++ b/src/Language/PureScript/CoreFn/Pretty.hs @@ -0,0 +1,82 @@ +module Language.PureScript.CoreFn.Pretty ( + module PRETTY, + ppType, + smartRender, + writeModule, + prettyModuleTxt, + prettyModuleStr, + renderExpr, + renderExprStr, + prettyTypeStr +) where + +import Prelude hiding ((<>)) + +import Data.Text (Text) +import Data.Text qualified as T + +import System.IO (Handle) + +import Language.PureScript.CoreFn.Expr + ( Expr(..), Bind ) +import Language.PureScript.Types (Type (..)) +import Language.PureScript.CoreFn.Module (Module) + +import Language.PureScript.CoreFn.Pretty.Common as PRETTY +import Language.PureScript.CoreFn.Pretty.Expr as PRETTY +import Language.PureScript.CoreFn.Pretty.Types as PRETTY + +import Prettyprinter + ( Pretty (pretty), + layoutSmart, + defaultLayoutOptions, + layoutPretty, + Doc ) +import Prettyprinter.Render.Text ( renderIO, renderStrict ) + + +{- Rewritten prettyprinter that uses a modern printer library & is less convoluted. + + We primarily need this for writing the "prettified" CoreFn files for development purposes. + The existing printer is extremely difficult to modify for our needs (e.g. there isn't a clear way to force + an expression or type to print on one line). Because reading the CoreFn output is necessary + to ensure correctness, it's important that we get get something legible. +-} + + +-- TODO: Remove +ppType :: Show a => Int -> Type a -> String +ppType _ t = prettyTypeStr t + + +-- TODO (maybe): It wouldn't be too hard to determine the terminal width and write a +-- display function that prints correctly-formatted-for-the-size +smartRender :: Doc ann -> Text +smartRender = renderStrict . layoutPretty defaultLayoutOptions + +writeModule :: Handle -> Module (Bind a) a -> IO () +writeModule h m = renderIO h + . layoutSmart defaultLayoutOptions + $ prettyModule m + +prettyModuleTxt :: Module (Bind a) a -> Text +prettyModuleTxt = renderStrict . layoutPretty defaultLayoutOptions . prettyModule + +prettyModuleStr :: Module (Bind a) a -> String +prettyModuleStr = T.unpack . prettyModuleTxt + +renderExpr :: Expr a -> Text +renderExpr = smartRender . asDynamic prettyValue + +renderExprStr :: Expr a -> String +renderExprStr = T.unpack . renderExpr + +prettyTypeStr :: forall a. Show a => Type a -> String +prettyTypeStr = T.unpack . smartRender . asOneLine prettyType + + +{- TYPES (move later) -} + +-- TODO: Move +instance Show a => Pretty (Type a) where + pretty t = pretty $ prettyTypeStr t diff --git a/src/Language/PureScript/CoreFn/Pretty/Common.hs b/src/Language/PureScript/CoreFn/Pretty/Common.hs new file mode 100644 index 000000000..1b76f48b9 --- /dev/null +++ b/src/Language/PureScript/CoreFn/Pretty/Common.hs @@ -0,0 +1,204 @@ +module Language.PureScript.CoreFn.Pretty.Common where + +import Prelude hiding ((<>)) + +import Control.Monad.Reader ( MonadReader(ask), runReader, Reader ) + +import Language.PureScript.CoreFn.Expr + ( Expr(..) ) +import Language.PureScript.Label (Label (..)) +import Language.PureScript.Names (runModuleName, showIdent, Ident, ModuleName) +import Language.PureScript.PSString (PSString, decodeStringWithReplacement) + +import Prettyprinter + ( (<>), + brackets, + hardline, + (<+>), + rbrace, + lbrace, + rparen, + lparen, + pipe, + comma, + punctuate, + indent, + line, + space, + vcat, + hcat, + vsep, + hsep, + flatAlt, + align, + group, + Doc, + Pretty(pretty) ) + +{- One thing that we often wish to do, but cannot easily do either with + the Prettyprinter library or the ancient lib PureScript uses, is to + *force* particular sub-expressions to print on a single line. + + (`Prettyprinter.group` does give us the ability to express: "Try to + print this on one line, but if you can't, use the multi-line format", and we + use that when choosing between one- and multi-line formats.) + + This gives us a nice little abstraction for convenient auto-formatting + (single line/multi line) where we want it, while also giving us the ability to + override particular locations in the AST that we want to force to one-line (e.g. case + expression binders, applied types, etc). +-} +data LineFormat + = OneLine -- *DEFINITELY* Print on one line, even if doing so exceeds the page width + | MultiLine -- *Possibly* Print multiple lines. + deriving (Show, Eq) + +-- A document with a structure that depends on a formatting context +type Printer ann = Reader LineFormat (Doc ann) + +-- Convenience type +type Formatter = forall a ann. (a -> Printer ann) -> a -> Doc ann + +-- runReader with flipped arguments (how it should be!) +runPrinter :: LineFormat -> Printer ann -> Doc ann +runPrinter fmt p = runReader p fmt + +asOneLine :: Formatter +asOneLine p x = runPrinter OneLine (p x) + +-- Helper for dynamic formatting. `asMultiLine` doesn't make sense (we always want to choose +-- between single and multiline formats in a context where we aren't forcing a one-line format) +asDynamic :: Formatter +asDynamic p x = group $ align $ flatAlt (runPrinter MultiLine (p x)) (runPrinter OneLine (p x)) + +-- Applies the supplied function to the Doc if we're in a Multiline context. +-- Primarily used for correct formatting of Records/Rows/Objects +onMultiline :: (Doc ann -> Doc ann) -> Doc ann -> Printer ann +onMultiline f doc = ask >>= \case + OneLine -> pure doc + MultiLine -> pure . f $ doc + +-- For docs w/ a structure that does not vary based on the line format options +-- Used primarily for `let` expressions (where we want uniformity) +ignoreFmt :: Doc ann -> Printer ann +ignoreFmt doc = printer doc doc + +-- Choose between hsep and vsep based on the context +fmtSep :: [Doc ann] -> Printer ann +fmtSep docs = ask >>= \case + OneLine -> pure $ hsep docs + MultiLine -> pure $ vsep docs + +-- Choose between hcat and vcat based on the context +fmtCat :: [Doc ann] -> Printer ann +fmtCat docs = ask >>= \case + OneLine -> pure $ hcat docs + MultiLine -> pure $ vcat docs + +-- Choose between newline + indent or no change, depending on the context. +-- NOTE: This is kind of the whole reason we need LineFormat + the Reader monad. +-- `group` isn't sufficient here +fmtIndent :: Doc ann -> Printer ann +fmtIndent doc = ask >>= \case + OneLine -> pure doc + MultiLine -> pure $ line <> indent 2 doc + +-- Helper function for constructing a printer expr +printer :: Doc ann -> Doc ann -> Printer ann +printer one multi = ask >>= \case + OneLine -> pure one + MultiLine -> pure multi + +{- Higher-order Printers for Row Types, Record Types, and Object lits -} + +-- Helper for open rows. The `| r` part requires special handling. +withOpenRow :: forall ann. Doc ann -> Doc ann -> ([Doc ann],Doc ann) -> Printer ann +withOpenRow l r (fields,open) = do + fmtFields <- onMultiline (indent 2) =<< fmtSep (punctuate comma fields') + group . align <$> fmtSep [l,fmtFields, r] -- fmtFields + where + fields' = foldr (\x acc -> case acc of + [] -> [hsep [x,pipe <+> open]] + xs -> x : xs + ) [] fields + +openRow :: ([Doc ann], Doc ann) -> Printer ann +openRow = withOpenRow lparen rparen + +openRecord :: ([Doc ann], Doc ann) -> Printer ann +openRecord = withOpenRow lbrace rbrace + +-- Printer for record like things (Object literals, record types) +recordLike :: [Doc ann] -> Printer ann +recordLike fields = do + fields' <- onMultiline (indent 2) =<< fmtSep (punctuate comma fields) + group . align <$> fmtSep [lbrace,fields',rbrace] + +{- Misc Utils and custom combinators. + Most of these are just for readability. (a <:> type), + to me anyway, is a lot easier on the eyes than + (a <> ":" <> space <> type) +-} +commaSep :: [Doc ann] -> Doc ann +commaSep = vsep . punctuate comma + +-- Our "special" type annotations are indicated w/ a single colon. +(<:>) :: Doc ann -> Doc ann -> Doc ann +a <:> b = hcat [a,":"] <+> b + +-- Actual type annotations & signatures (that are in the source explicitly or +-- inferred by the compiler before we get the AST) are indicated in the normal way, +-- that is, with '::' +(<::>) :: Doc ann -> Doc ann -> Doc ann +a <::> b = a <+> "::" <+> b + +(<=>) :: Doc ann -> Doc ann -> Doc ann +a <=> b = a <+> "=" <+> b + +-- Forces a line break. Shouldn't be used except in cases where we want to ignore +-- the dynamic formatting (e.g. case expressions) +() :: Doc ann -> Doc ann -> Doc ann +a b = a <+> hardline <+> b + +arrow :: Doc ann +arrow = "->" + +lam :: Doc ann +lam = "\\" + +-- Like `list` but forces one line format. +oneLineList :: [Doc ann] -> Doc ann +oneLineList = brackets . hcat . punctuate (comma <> space) + +-- Splits an `App` expr into a function/ctor and a list of arguments. +analyzeApp :: Expr a -> Maybe (Expr a,[Expr a]) +analyzeApp t = (,appArgs t) <$> appFun t + where + appArgs :: Expr a -> [Expr a] + appArgs (App _ t1 t2) = appArgs t1 <> [t2] + appArgs _ = [] + + appFun :: Expr a -> Maybe (Expr a) + appFun (App _ t1 _) = go t1 + where + go (App _ tx _) = case appFun tx of + Nothing -> Just tx + Just tx' -> Just tx' + go other = Just other + appFun _ = Nothing + + + + +-- TODO: Move to modules where types are defined +instance Pretty Ident where + pretty = pretty . showIdent + +instance Pretty PSString where + pretty = pretty . decodeStringWithReplacement + +instance Pretty ModuleName where + pretty = pretty . runModuleName + +instance Pretty Label where + pretty = pretty . runLabel diff --git a/src/Language/PureScript/CoreFn/Pretty/Expr.hs b/src/Language/PureScript/CoreFn/Pretty/Expr.hs new file mode 100644 index 000000000..14fbb85b5 --- /dev/null +++ b/src/Language/PureScript/CoreFn/Pretty/Expr.hs @@ -0,0 +1,262 @@ +{-# LANGUAGE TypeApplications, ScopedTypeVariables #-} +module Language.PureScript.CoreFn.Pretty.Expr where + + +import Prelude hiding ((<>)) + +import Data.Text (Text) +import Data.Text qualified as T +import Data.Map qualified as M +import Data.Bifunctor (Bifunctor (..)) +import Control.Monad.Reader ( MonadReader(ask), runReader ) + +import Language.PureScript.Environment + ( getFunArgTy ) +import Language.PureScript.CoreFn.Expr + ( Guard, + Bind(..), + CaseAlternative(CaseAlternative), + Expr(..) ) +import Language.PureScript.CoreFn.Module ( Module(Module) ) +import Language.PureScript.CoreFn.Utils +import Language.PureScript.AST.Literals ( Literal(..) ) +import Language.PureScript.CoreFn.Binders ( Binder(..) ) +import Language.PureScript.Names (ProperName(..), disqualify, showIdent, Ident, ModuleName) +import Language.PureScript.PSString (PSString, prettyPrintString, decodeStringWithReplacement) + +import Prettyprinter + ( (<>), + list, + viaShow, + colon, + parens, + dot, + hardline, + (<+>), + punctuate, + indent, + line, + space, + vcat, + hcat, + vsep, + hsep, + flatAlt, + align, + group, + Doc, + Pretty(pretty) ) +import Language.PureScript.CoreFn.Pretty.Common + ( Printer, + LineFormat(MultiLine, OneLine), + asOneLine, + asDynamic, + ignoreFmt, + fmtSep, + fmtCat, + fmtIndent, + printer, + recordLike, + commaSep, + (<:>), + (<::>), + (<=>), + (), + arrow, + lam, + oneLineList, + analyzeApp ) +import Language.PureScript.CoreFn.Pretty.Types ( prettyType ) + +-- TODO: DataDecls +prettyModule :: Module (Bind a) a -> Doc ann +prettyModule (Module _ _ modName modPath modImports modExports modReExports modForeign modDecls _) = + vsep + [ pretty modName <+> parens (pretty modPath) + , "Imported Modules: " + , indent 2 . commaSep $ pretty . snd <$> modImports + ,"Exports: " + , indent 2 . commaSep $ pretty <$> modExports -- hang 2? + , "Re-Exports: " + , indent 2 . commaSep $ goReExport <$> M.toList modReExports + , "Foreign: " + , indent 2 . commaSep . map pretty $ modForeign + , "Declarations: " + , vcat . punctuate line $ asDynamic prettyDeclaration <$> modDecls + ] + where + goReExport :: (ModuleName,[Ident]) -> Doc ann + goReExport (mn',idents) = vcat $ flip map idents $ \i -> pretty mn' <> "." <> pretty i + +-- Is a printer for consistency mainly +prettyObjectKey :: PSString -> Printer ann +prettyObjectKey = pure . pretty . decodeStringWithReplacement + +prettyObject :: [(PSString, Maybe (Expr a))] -> Printer ann +prettyObject fields = do + fields' <- traverse prettyProperty fields + recordLike fields' + where + prettyProperty :: (PSString, Maybe (Expr a)) -> Printer ann + prettyProperty (key, value) = do + key' <- prettyObjectKey key + props' <- maybe (pure $ pretty @Text "_") prettyValue value + pure (key' <:> props') + +prettyUpdateEntry :: PSString -> Expr a -> Printer ann +prettyUpdateEntry key val = do + key' <- prettyObjectKey key + val' <- prettyValue val + pure $ key' <=> val' + +-- | Pretty-print an expression +prettyValue :: Expr a -> Printer ann +prettyValue (Accessor _ _ prop val) = do + prop' <- prettyObjectKey prop + val' <- prettyValueAtom val + fmtCat [val',hcat[dot,prop']] +prettyValue (ObjectUpdate _ _ty o _copyFields ps) = do + obj <- prettyValueAtom o + updateEntries <- traverse goUpdateEntry ps >>= recordLike + pure $ obj <+> updateEntries + where + goUpdateEntry = uncurry prettyUpdateEntry +prettyValue app@(App _ t1 t2) = case analyzeApp app of + Just (fun,args) -> do + atom <- fmtSep =<< traverse prettyValueAtom (fun:args) + pure . group . align $ atom + -- ty <- prettyType $ appType t1 t2 + -- pure . group . align $ parens (atom <:> ty) + {- TODO: change back + ask >>= \case + OneLine -> pure . group . align . hsep . map (asOneLine prettyValueAtom) $ (fun:args) + MultiLine -> pure . group . align . vsep . map (asDynamic prettyValueAtom) $ (fun:args) -} + Nothing -> error "App isn't an App (impossible)" +prettyValue (Abs _ ty arg val) = do + ty' <- prettyType (getFunArgTy ty) + body' <- fmtIndent =<< prettyValue val + pure $ lam + <> parens (align $ pretty (showIdent arg) <:> ty') + <+> arrow + <+> body' +-- TODO: Actually implement the one line bracketed format for case exps (I think PS is the same as Haskell?) +prettyValue (Case _ _ values binders) = pure $ + "case" + <+> group (hsep scrutinees) + <+> "of" + indent 2 (vcat $ map group branches) + where + scrutinees = asOneLine prettyValueAtom <$> values + branches = group . asDynamic prettyCaseAlternative <$> binders +-- technically we could have a one line version of this but that's ugly af imo +prettyValue (Let _ ds val) = pure . align $ vcat [ + "let", + indent 2 . vcat $ asDynamic prettyDeclaration <$> ds, + "in" <+> align (asDynamic prettyValue val) + ] +prettyValue (Literal _ ty l) = ask >>= \case {OneLine -> oneLine; MultiLine -> multiLine} + where + -- No type anns for object literals (already annotated in the fields, makes too ugly) + oneLine = pure . parens $ asOneLine prettyLiteralValue l <:> asOneLine prettyType ty + multiLine = pure . parens $ asDynamic prettyLiteralValue l <:> asDynamic prettyType ty + +prettyValue expr@Constructor{} = prettyValueAtom expr +prettyValue expr@Var{} = prettyValueAtom expr + +-- | Pretty-print an atomic expression, adding parentheses if necessary. +prettyValueAtom :: Expr a -> Printer ann +prettyValueAtom lit@(Literal _ _ l) = prettyValue lit -- prettyLiteralValue l +prettyValueAtom (Constructor _ _ _ name _) = pure . pretty $ T.unpack $ runProperName name +prettyValueAtom (Var _ ty ident) = prettyType ty >>= \ty' -> + pure . parens $ pretty (showIdent (disqualify ident)) <:> ty' +prettyValueAtom expr = do -- TODO change this back (need more anns for testing) + v <- prettyValue expr + -- t <- prettyType (exprType expr) + pure $ parens v -- <:> t) + +prettyLiteralValue :: Literal (Expr a) -> Printer ann +prettyLiteralValue (NumericLiteral n) = ignoreFmt $ pretty $ either show show n +prettyLiteralValue (StringLiteral s) = ignoreFmt $ pretty . T.unpack $ prettyPrintString s +prettyLiteralValue (CharLiteral c) = ignoreFmt $ viaShow . show $ c +prettyLiteralValue (BooleanLiteral True) = ignoreFmt "true" +prettyLiteralValue (BooleanLiteral False) = ignoreFmt "false" +prettyLiteralValue (ArrayLiteral xs) = printer oneLine multiLine + where + oneLine = oneLineList $ asOneLine prettyValue <$> xs + -- N.B. I think it makes more sense to ensure that list *elements* are always oneLine + multiLine = list $ asOneLine prettyValue <$> xs +prettyLiteralValue (ObjectLiteral ps) = prettyObject $ second Just `map` ps + +prettyDeclaration :: forall a ann. Bind a -> Printer ann +prettyDeclaration b = case b of + NonRec _ ident expr -> goBind ident expr + Rec bindings -> vcat <$> traverse (\((_,ident),expr) -> goBind ident expr) bindings + where + goBind :: Ident -> Expr a -> Printer ann + goBind ident expr = do + inner' <- goInner ident expr + let ty' = asOneLine prettyType (exprType expr) + pure $ + pretty ident <::> ty' + <> hardline + <> inner' + goInner :: Ident -> Expr a -> Printer ann + goInner ident expr = do + fmt <- ask + let ind docs = runReader (fmtIndent docs) fmt + f g = pretty ident <=> g (asDynamic prettyValue expr) + pure $ group $ flatAlt (f ind) (f id) + +prettyCaseAlternative :: forall a ann. CaseAlternative a -> Printer ann +prettyCaseAlternative (CaseAlternative binders result) = do + let binders' = asOneLine prettyBinderAtom <$> binders + result' <- prettyResult result + pure $ hsep binders' <> result' + where + prettyResult :: Either [(Guard a, Expr a)] (Expr a) -> Printer ann + prettyResult = \case + Left ges -> vcat <$> traverse prettyGuardedValueSep' ges + Right exp' -> do + body' <- prettyValue exp' >>= fmtIndent + pure $ space <> arrow <+> body' + + prettyGuardedValueSep' :: (Guard a, Expr a) -> Printer ann + prettyGuardedValueSep' (guardE, resultE) = do + guardE' <- prettyValue guardE + resultE' <- prettyValue resultE + pure $ " | " <> guardE' <+> arrow <+> resultE' + + + + +prettyBinderAtom :: Binder a -> Printer ann +prettyBinderAtom (NullBinder _) = pure "_" +prettyBinderAtom (LiteralBinder _ l) = prettyLiteralBinder l +prettyBinderAtom (VarBinder _ ident) = pure $ pretty ident +prettyBinderAtom (ConstructorBinder _ _ ctor []) = pure . pretty $ runProperName (disqualify ctor) +prettyBinderAtom b@ConstructorBinder{} = prettyBinder b +prettyBinderAtom (NamedBinder _ ident binder)= do + binder' <- prettyBinder binder + pure $ pretty ident <> "@" <> binder' + +prettyLiteralBinder :: Literal (Binder a) -> Printer ann +prettyLiteralBinder (StringLiteral str) = pure . pretty $ prettyPrintString str +prettyLiteralBinder (CharLiteral c) = pure $ viaShow c +prettyLiteralBinder (NumericLiteral num) = pure $ either pretty pretty num +prettyLiteralBinder (BooleanLiteral True) = pure "true" +prettyLiteralBinder (BooleanLiteral False) = pure "false" +prettyLiteralBinder (ObjectLiteral bs) = recordLike =<< traverse prettyObjectPropertyBinder bs + where + prettyObjectPropertyBinder :: (PSString, Binder a) -> Printer ann + prettyObjectPropertyBinder (key, binder) = do + key' <- prettyObjectKey key + binder' <- prettyBinder binder + pure $ key' <:> binder' +prettyLiteralBinder (ArrayLiteral bs) = list <$> traverse prettyBinder bs + +prettyBinder :: Binder a -> Printer ann +prettyBinder (ConstructorBinder _ _ ctor []) = pure . pretty $ runProperName (disqualify ctor) +prettyBinder (ConstructorBinder _ _ ctor args) = do + args' <- fmtSep =<< traverse prettyBinderAtom args + pure $ pretty (runProperName (disqualify ctor)) <+> args' -- fmtSep fmt (asFmt fmt prettyBinderAtom <$> args) +prettyBinder b = prettyBinderAtom b diff --git a/src/Language/PureScript/CoreFn/Pretty/Types.hs b/src/Language/PureScript/CoreFn/Pretty/Types.hs new file mode 100644 index 000000000..23e569896 --- /dev/null +++ b/src/Language/PureScript/CoreFn/Pretty/Types.hs @@ -0,0 +1,157 @@ +module Language.PureScript.CoreFn.Pretty.Types (prettyType) where + +import Prelude hiding ((<>)) + +import Data.Text (Text) +import Data.Bifunctor (first, Bifunctor (..)) +import Control.Monad.Reader ( MonadReader(ask), Reader ) + +import Language.PureScript.Environment + ( tyRecord, tyFunction, pattern ArrayT ) +import Language.PureScript.Names (OpName(..), ProperName(..), disqualify, showQualified) +import Language.PureScript.Types (Type (..), WildcardData (..), TypeVarVisibility (..), eqType) +import Language.PureScript.PSString (prettyPrintString) + +import Prettyprinter + ( (<>), + tupled, + parens, + (<+>), + hcat, + group, + Doc, + Pretty(pretty) ) +import Language.PureScript.CoreFn.Pretty.Common + ( Printer, + LineFormat, + runPrinter, + fmtSep, + openRow, + openRecord, + recordLike, + (<::>), + arrow, asOneLine ) +-- need for debugging +import Prettyprinter + ( layoutSmart, + defaultLayoutOptions, + layoutPretty, + Doc ) +import Prettyprinter.Render.Text ( renderIO, renderStrict ) +import Data.Text (Text) +import Data.Text qualified as T + + +prettyType :: forall a ann. Show a => Type a -> Printer ann +prettyType t = group <$> case t of + ArrayT tx -> do -- this is a stupid hack, figure out the proper fix later + inner <- parens <$> prettyType tx + pure $ "Array" <+> inner + + TUnknown _ n -> pure $ "t" <> pretty n + + TypeVar _ txt -> pure $ pretty txt + + TypeLevelString _ pss -> pure . pretty . prettyPrintString $ pss + + TypeLevelInt _ i -> pure $ pretty i + + TypeWildcard _ wcd -> case wcd of + HoleWildcard txt -> pure $ "?" <> pretty txt + _ -> pure "_" + + TypeConstructor _ qPropName -> pure . pretty . runProperName . disqualify $ qPropName + + TypeOp _ opName -> pure . pretty $ showQualified runOpName opName + + TypeApp _ t1 t2 -> goTypeApp t1 t2 + + KindApp _ k1 k2 -> do + k1' <- prettyType k1 + k2' <- prettyType k2 + pure $ k1' <> ("@" <> k2' ) + + ForAll _ vis var mKind inner' _ -> case stripQuantifiers inner' of + (quantified,inner) -> goForall ([(vis,var,mKind)] <> quantified) inner + + ConstrainedType _ _ _ -> error "TODO: ConstrainedType (shouldn't ever appear in Purus CoreFn)" + + Skolem _ var _ i _ -> pure $ pretty var <> "#" <> pretty i + + REmpty _ -> pure "{}" + + rcons@RCons{} -> either openRow (pure . tupled) =<< rowFields rcons + + -- this might be backwards + KindedType _ ty kind -> do + ty' <- prettyType ty + kind' <- prettyType kind + pure . parens $ ty' <::> kind' -- prettyType ty fmt <::> prettyType kind fmt + + -- not sure what this is? + BinaryNoParensType _ op l r -> do + l' <- prettyType l + op' <- prettyType op + r' <- prettyType r + pure $ l' <+> op' <+> r' -- prettyType l fmt <+> prettyType op fmt <+> prettyType r fmt + + ParensInType _ ty -> parens <$> prettyType ty + where + goForall :: [(TypeVarVisibility,Text,Maybe (Type a))] -> Type a -> Printer ann + goForall xs inner = do + boundVars <- fmtSep =<< traverse renderBoundVar xs + inner' <- prettyType inner + pure $ + "forall" <+> boundVars <> "." <+> inner' + + prefixVis :: TypeVarVisibility -> Doc ann -> Doc ann + prefixVis vis tv = case vis of + TypeVarVisible -> hcat ["@",tv] + TypeVarInvisible -> tv + + renderBoundVar :: (TypeVarVisibility, Text, Maybe (Type a)) -> Printer ann + renderBoundVar (vis,var,mk) = case mk of + Just k -> do + ty' <- prettyType k + pure . parens $ prefixVis vis (pretty var) <::> ty' + Nothing -> pure $ prefixVis vis (pretty var) + + stripQuantifiers :: Type a -> ([(TypeVarVisibility,Text,Maybe (Type a))],Type a) + stripQuantifiers = \case + ForAll _ vis var mk inner _ -> first ((vis,var,mk):) $ stripQuantifiers inner + other -> ([],other) + + goTypeApp :: Type a -> Type a -> Printer ann + goTypeApp (TypeApp _ f a) b + | eqType f tyFunction = do + a' <- prettyType a + b' <- prettyType b + fmtSep [a' <+> arrow,b'] + | otherwise = do + f' <- goTypeApp f a + b' <- prettyType b + pure $ parens $ f' <+> b' + goTypeApp o ty@RCons{} + | eqType o tyRecord = + either openRecord recordLike =<< rowFields ty + goTypeApp a b = fmtSep =<< traverse prettyType [a,b] + + rowFields :: Type a -> Reader LineFormat (Either ([Doc ann], Doc ann) [Doc ann]) + rowFields = \case + RCons _ lbl ty rest -> do + fmt <- ask + let f = ((pretty lbl <::> runPrinter fmt (prettyType ty)):) + rest' <- rowFields rest + pure $ bimap (first f) f rest' + REmpty _ -> pure $ Right [] + KindApp _ REmpty{} _ -> pure $ Right [] -- REmpty is sometimes wrapped in a kind app + TypeVar _ txt -> pure $ Left ([],pretty txt) + other -> Right . pure <$> prettyType other -- error $ "Malformed row fields: \n" <> prettyTypeStr other + + +-- TODO For debugging, remove later +smartRender :: Doc ann -> Text +smartRender = renderStrict . layoutPretty defaultLayoutOptions + +prettyTypeStr :: forall a. Show a => Type a -> String +prettyTypeStr = T.unpack . smartRender . asOneLine prettyType diff --git a/src/Language/PureScript/CoreFn/ToJSON.hs b/src/Language/PureScript/CoreFn/ToJSON.hs index 1b20ac4e6..d97674f02 100644 --- a/src/Language/PureScript/CoreFn/ToJSON.hs +++ b/src/Language/PureScript/CoreFn/ToJSON.hs @@ -5,6 +5,7 @@ -- module Language.PureScript.CoreFn.ToJSON ( moduleToJSON + , moduleToJSON' ) where import Prelude @@ -116,7 +117,7 @@ qualifiedToJSON f (Qualified qb a) = moduleNameToJSON :: ModuleName -> Value moduleNameToJSON (ModuleName name) = toJSON (T.splitOn (T.pack ".") name) -moduleToJSON :: Version -> Module Ann -> Value +moduleToJSON :: Version -> Module (Bind Ann) Ann -> Value moduleToJSON v m = object [ "sourceSpan" .= sourceSpanToJSON (moduleSourceSpan m) , "moduleName" .= moduleNameToJSON (moduleName m) @@ -128,6 +129,7 @@ moduleToJSON v m = object , "decls" .= map bindToJSON (moduleDecls m) , "builtWith" .= toJSON (showVersion v) , "comments" .= map toJSON (moduleComments m) + , "dataTypes" .= toJSON (moduleDataTypes m) ] where @@ -139,6 +141,30 @@ moduleToJSON v m = object reExportsToJSON :: M.Map ModuleName [Ident] -> Value reExportsToJSON = toJSON . M.map (map runIdent) + +moduleToJSON' :: Module (Bind Ann) Ann -> Value +moduleToJSON' m = object + [ "sourceSpan" .= sourceSpanToJSON (moduleSourceSpan m) + , "moduleName" .= moduleNameToJSON (moduleName m) + , "modulePath" .= toJSON (modulePath m) + , "imports" .= map importToJSON (moduleImports m) + , "exports" .= map identToJSON (moduleExports m) + , "reExports" .= reExportsToJSON (moduleReExports m) + , "foreign" .= map identToJSON (moduleForeign m) + , "decls" .= map bindToJSON (moduleDecls m) + , "comments" .= map toJSON (moduleComments m) + , "dataTypes" .= toJSON (moduleDataTypes m) + ] + where + importToJSON (ann,mn) = object + [ "annotation" .= annToJSON ann + , "moduleName" .= moduleNameToJSON mn + ] + + reExportsToJSON :: M.Map ModuleName [Ident] -> Value + reExportsToJSON = toJSON . M.map (map runIdent) + + bindToJSON :: Bind Ann -> Value bindToJSON (NonRec ann n e) = object @@ -162,50 +188,57 @@ recordToJSON :: (a -> Value) -> [(PSString, a)] -> Value recordToJSON f = toJSON . map (toJSON *** f) exprToJSON :: Expr Ann -> Value -exprToJSON (Var ann i) = object [ "type" .= toJSON "Var" +exprToJSON (Var ann ty i) = object [ "kind" .= toJSON "Var" + , "type" .= toJSON ty , "annotation" .= annToJSON ann , "value" .= qualifiedToJSON runIdent i ] -exprToJSON (Literal ann l) = object [ "type" .= "Literal" +exprToJSON (Literal ann ty l) = object [ "kind" .= "Literal" + , "type" .= toJSON ty , "annotation" .= annToJSON ann , "value" .= literalToJSON exprToJSON l ] -exprToJSON (Constructor ann d c is) = object [ "type" .= "Constructor" +exprToJSON (Constructor ann ty d c is) = object [ "kind" .= "Constructor" + , "type" .= toJSON ty , "annotation" .= annToJSON ann , "typeName" .= properNameToJSON d , "constructorName" .= properNameToJSON c , "fieldNames" .= map identToJSON is ] -exprToJSON (Accessor ann f r) = object [ "type" .= "Accessor" +exprToJSON (Accessor ann ty f r) = object [ "kind" .= "Accessor" + , "type" .= toJSON ty , "annotation" .= annToJSON ann , "fieldName" .= f , "expression" .= exprToJSON r ] -exprToJSON (ObjectUpdate ann r copy fs) - = object [ "type" .= "ObjectUpdate" +exprToJSON (ObjectUpdate ann ty r copy fs) + = object [ "kind" .= "ObjectUpdate" + , "type" .= toJSON ty , "annotation" .= annToJSON ann , "expression" .= exprToJSON r , "copy" .= toJSON copy , "updates" .= recordToJSON exprToJSON fs ] -exprToJSON (Abs ann p b) = object [ "type" .= "Abs" +exprToJSON (Abs ann ty p b) = object [ "kind" .= "Abs" + , "type" .= toJSON ty , "annotation" .= annToJSON ann , "argument" .= identToJSON p , "body" .= exprToJSON b ] -exprToJSON (App ann f x) = object [ "type" .= "App" +exprToJSON (App ann f x) = object [ "kind" .= "App" , "annotation" .= annToJSON ann , "abstraction" .= exprToJSON f , "argument" .= exprToJSON x ] -exprToJSON (Case ann ss cs) = object [ "type" .= "Case" +exprToJSON (Case ann ty ss cs) = object [ "kind" .= "Case" + , "type" .= toJSON ty , "annotation" .= annToJSON ann , "caseExpressions" .= map exprToJSON ss , "caseAlternatives" .= map caseAlternativeToJSON cs ] -exprToJSON (Let ann bs e) = object [ "type" .= "Let" +exprToJSON (Let ann bs e) = object [ "kind" .= "Let" , "annotation" .= annToJSON ann , "binds" .= map bindToJSON bs , "expression" .= exprToJSON e diff --git a/src/Language/PureScript/CoreFn/Traversals.hs b/src/Language/PureScript/CoreFn/Traversals.hs index f0684d34d..7bb5c1885 100644 --- a/src/Language/PureScript/CoreFn/Traversals.hs +++ b/src/Language/PureScript/CoreFn/Traversals.hs @@ -21,12 +21,12 @@ everywhereOnValues f g h = (f', g', h') f' (NonRec a name e) = f (NonRec a name (g' e)) f' (Rec es) = f (Rec (map (second g') es)) - g' (Literal ann e) = g (Literal ann (handleLiteral g' e)) - g' (Accessor ann prop e) = g (Accessor ann prop (g' e)) - g' (ObjectUpdate ann obj copy vs) = g (ObjectUpdate ann (g' obj) copy (map (fmap g') vs)) - g' (Abs ann name e) = g (Abs ann name (g' e)) + g' (Literal ann t e) = g (Literal ann t (handleLiteral g' e)) + g' (Accessor ann t prop e) = g (Accessor ann t prop (g' e)) + g' (ObjectUpdate ann t obj copy vs) = g (ObjectUpdate ann t (g' obj) copy (map (fmap g') vs)) + g' (Abs ann t name e) = g (Abs ann t name (g' e)) g' (App ann v1 v2) = g (App ann (g' v1) (g' v2)) - g' (Case ann vs alts) = g (Case ann (map g' vs) (map handleCaseAlternative alts)) + g' (Case ann t vs alts) = g (Case ann t (map g' vs) (map handleCaseAlternative alts)) g' (Let ann ds e) = g (Let ann (map f' ds) (g' e)) g' e = g e @@ -64,13 +64,13 @@ traverseCoreFn f g h i = (f', g', h', i') f' (NonRec a name e) = NonRec a name <$> g e f' (Rec es) = Rec <$> traverse (traverse g) es - g' (Literal ann e) = Literal ann <$> handleLiteral g e - g' (Accessor ann prop e) = Accessor ann prop <$> g e - g' (ObjectUpdate ann obj copy vs) = (\obj' -> ObjectUpdate ann obj' copy) <$> g obj <*> traverse (traverse g) vs - g' (Abs ann name e) = Abs ann name <$> g e + g' (Literal ann t e) = Literal ann t <$> handleLiteral g e + g' (Accessor ann t prop e) = Accessor ann t prop <$> g e + g' (ObjectUpdate ann t obj copy vs) = (\obj' -> ObjectUpdate ann t obj' copy) <$> g obj <*> traverse (traverse g) vs + g' (Abs ann t name e) = Abs ann t name <$> g e g' (App ann v1 v2) = App ann <$> g v1 <*> g v2 - g' (Case ann vs alts) = Case ann <$> traverse g vs <*> traverse i alts - g' (Let ann ds e) = Let ann <$> traverse f ds <*> g' e + g' (Case ann t vs alts) = Case ann t <$> traverse g vs <*> traverse i alts + g' (Let ann ds e) = Let ann <$> traverse f ds <*> g' e g' e = pure e h' (LiteralBinder a b) = LiteralBinder a <$> handleLiteral h b diff --git a/src/Language/PureScript/CoreFn/TypeLike.hs b/src/Language/PureScript/CoreFn/TypeLike.hs new file mode 100644 index 000000000..bbf10a80f --- /dev/null +++ b/src/Language/PureScript/CoreFn/TypeLike.hs @@ -0,0 +1,98 @@ +module Language.PureScript.CoreFn.TypeLike where + +import Language.PureScript.Types (TypeVarVisibility) +import Data.Text (Text) +import Prelude + +import Language.PureScript.Types qualified as T +import Language.PureScript.Environment qualified as E +import Data.Bifunctor (Bifunctor(..)) + +class TypeLike t where + {- | Usually this will be the Type Application constructor -} + applyType :: t -> t -> t + + {- | Given a typelike, remove all of the leading quantifiers while + keeping track of the quantifier metadata (visibility, name, kind) + for each removed quantifier. + -} + stripQuantifiers :: t -> ([(TypeVarVisibility, Text, Maybe t)], t) + + {- Given TypeLikes `a` and `b`, construct a function type `a -> b` + -} + funTy :: t -> t -> t + + {- | (a -> b -> c) -> [a,b] + + NOTE: Unsafe/partial. Check that you don't want `splitFunTyParts` instead + -} + funArgTypes :: t -> [t] + funArgTypes = init . splitFunTyParts + + {- | Replaces all the type variables with the corresponding types -} + replaceAllTypeVars :: [(Text,t)] -> t -> t + + {- | (a -> b -> c) -> [a,b,c] + + NOTE: Check that you don't want `funArgTypes` instead + -} + splitFunTyParts :: t -> [t] + + {- | Quantify over all free type variables in the argument type. + -} + quantify :: t -> t + + {- | `instantiates var mono poly` tries to find + the type in `mono` that instantiates the TyVar in + `poly`. + + E.g. `instantiates "x" (Maybe Int) (Maybe x) == Just Int` + -} + instantiates :: Text -- name of TyVar we're checking + -> t -- Monomorphic/"more monomorphic" type + -> t -- Polymorphic/"more polymorphic" type + -> Maybe t + + {- | Collect the used type variables in a type -} + usedTypeVariables :: t -> [Text] + + {- | Collect the free type variables in a type -} + freeTypeVariables :: t -> [Text] + + {- | Get the (final) return type of a function. Returns the argument + type if the argument is not a function. + -} + resultTy :: t -> t + +instance TypeLike T.SourceType where + applyType = T.srcTypeApp + + stripQuantifiers = \case + T.ForAll _ vis var mk inner _ -> first ((vis,var,mk):) $ stripQuantifiers inner + other -> ([],other) + + funTy = E.function + + funArgTypes = init . splitFunTyParts + + replaceAllTypeVars = T.replaceAllTypeVars + + splitFunTyParts = \case + (a E.:-> b) -> a : splitFunTyParts b + t -> [t] + + quantify = T.quantify + + instantiates var x (T.TypeVar _ y) | y == var = Just x + instantiates var (T.TypeApp _ t1 t2) (T.TypeApp _ t1' t2') = case instantiates var t1 t1' of + Just x -> Just x + Nothing -> instantiates var t2 t2' + instantiates _ _ _ = Nothing + + freeTypeVariables = T.freeTypeVariables + + usedTypeVariables = T.usedTypeVariables + + resultTy t = case snd $ stripQuantifiers t of + (_ E.:-> b) -> resultTy b + other -> other diff --git a/src/Language/PureScript/CoreFn/Utils.hs b/src/Language/PureScript/CoreFn/Utils.hs new file mode 100644 index 000000000..1c2f88086 --- /dev/null +++ b/src/Language/PureScript/CoreFn/Utils.hs @@ -0,0 +1,196 @@ +module Language.PureScript.CoreFn.Utils where + +import Prelude hiding (error) +import Data.Bifunctor ( Bifunctor(second, first) ) +import Language.PureScript.CoreFn.Expr +import Language.PureScript.CoreFn.Desugar.Utils ( traverseLit, showIdent' ) +import GHC.Natural ( Natural ) +import Data.Bitraversable (Bitraversable(bitraverse)) +import Control.Lens.IndexedPlated ( IndexedPlated(..), itransform ) +import Control.Lens ( Indexable(indexed), (^?) ) +import Language.PureScript.Types +import Data.Map (Map) +import Data.Map qualified as M +import Language.PureScript.Names (Ident, Qualified (..), QualifiedBy (..)) +import Data.Text (Text) + +import Language.PureScript.Environment (pattern (:->), function) +import Language.PureScript.CoreFn.Ann (Ann) +import Control.Lens.Type (Lens') + +type Context = Map Ident SourceType +{- +prettyContext :: Context -> String +prettyContext cxt = concatMap go (M.toList cxt) + where + go :: (Ident,SourceType) -> String + go (ident,ty) = showIdent' ident <> " := " <> prettyTypeStr ty <> "\n" +-} +instance IndexedPlated Context (Expr a) where + iplate d f = \case + Literal ann ty lit -> Literal ann ty <$> traverseLit (indexed f d) lit + Accessor ann ty field e -> Accessor ann ty field <$> indexed f d e + ObjectUpdate ann ty orig copyFields updateFields -> + (\orig' updateFields' -> ObjectUpdate ann ty orig' copyFields updateFields') + <$> indexed f d orig + <*> traverse (sequenceA . second (indexed f d)) updateFields + Abs ann ty ident body -> Abs ann ty ident <$> indexed f (M.insert ident (arg ty) d) body + App ann fE argE -> App ann <$> indexed f d fE <*> indexed f d argE + Case a ty scrutinees alternatives -> + Case a ty <$> traverse (indexed f d) scrutinees <*> traverseAltE d f alternatives + Let a binds e -> + Let a <$> traverseBinds d f binds <*> indexed f d e + other -> pure other -- ctors and vars don't contain any sub-expressions + where + arg = \case + ForAll _ _ _ _ inner _ -> arg inner + a :-> _ -> a + other -> other + + traverseBinds :: forall p f. (Indexable Context p, Applicative f) => Context -> p (Expr a) (f (Expr a)) -> [Bind a] -> f [Bind a] + traverseBinds cxt g binds = traverse (go cxt) binds + where + go :: Context -> Bind a -> f (Bind a) + go gCxt = \case + NonRec ann ident e -> + let cxt' = M.insert ident (exprType e) gCxt + in NonRec ann ident <$> indexed g cxt' e + Rec es -> Rec <$> goRecursive gCxt es + goRecursive :: Context -> [((a, Ident), Expr a)] -> f [((a, Ident), Expr a)] + goRecursive _ [] = pure [] + goRecursive gCxt (((ann,nm),e):rest) = + let gCxt' = M.insert nm (exprType e) gCxt + in (\x xs -> ((ann,nm),x):xs) <$> indexed g gCxt' e <*> goRecursive gCxt' rest + traverseAltE :: forall p f. (Indexable Context p, Applicative f) => Context -> p (Expr a) (f (Expr a)) -> [CaseAlternative a] -> f [CaseAlternative a] + traverseAltE cxt g alts = traverse (go cxt) alts + where + go :: Context -> CaseAlternative a -> f (CaseAlternative a) + go gCxt (CaseAlternative binders result) = + CaseAlternative binders + <$> helper gCxt result -- hellishly complex + helper :: Context -> Either [(Guard a, Expr a)] (Expr a) -> f (Either [(Guard a, Expr a)] (Expr a)) + helper gCxt = \case + Right e -> Right <$> indexed g gCxt e + Left es -> + let g' = indexed g gCxt + in Left <$> traverse (bitraverse g' g') es + +-- Bound tyVars and kinds. Idk if we'll use it but it takes like 10 seconds +type TyContext = Map Text (Maybe SourceType ) +-- Might be able to do something useful with a non-natural index (think about later) +instance IndexedPlated TyContext SourceType where + iplate d f = \case + TypeApp ann t1 t2 -> TypeApp ann <$> indexed f d t1 <*> indexed f d t2 + KindApp ann k1 t1 -> KindApp ann <$> indexed f d k1 <*> indexed f d t1 + ForAll a vis var mbK inner skol -> + let cxt = M.insert var mbK d + in (\mbK' inner' -> ForAll a vis var mbK' inner' skol) + <$> traverse (indexed f d) mbK + <*> indexed f cxt inner + -- \/ Just for completeness, they shouldn't exist + ConstrainedType ann c t1 -> ConstrainedType ann c <$> indexed f d t1 + RCons ann lbl t1 t2 -> RCons ann lbl <$> indexed f d t1 <*> indexed f d t2 + KindedType a t1 t2 -> KindedType a <$> indexed f d t1 <*> indexed f d t2 + BinaryNoParensType ann t1 t2 t3 -> + BinaryNoParensType ann + <$> indexed f d t1 + <*> indexed f d t2 + <*> indexed f d t3 + ParensInType ann t -> ParensInType ann <$> indexed f d t + -- nothing else has child types + other -> pure other + +{- TODO: REMOVE EVERYTHING BELOW (it should all be subsumed by the TypeLike class) + +-} + +-- TODO: Explain what this is / how it works +-- TODO: Type Constructors +instantiates :: Text -- Name of the TyVar we're checking + -> SourceType -- Monomorphic type (or "more monomorphic" type) + -> SourceType -- Polymorphic type (or "more polymoprhic" type) + -> Maybe SourceType +instantiates var x (TypeVar _ y) | y == var = Just x +instantiates var (TypeApp _ t1 t2) (TypeApp _ t1' t2') = case instantiates var t1 t1' of + Just x -> Just x + Nothing -> instantiates var t2 t2' +instantiates _ _ _ = Nothing + +appFunArgs :: Expr a -> Expr a -> (Expr a,[Expr a]) +appFunArgs f args = (appFun f, appArgs f args) + where + appArgs :: Expr a -> Expr a -> [Expr a] + appArgs (App _ t1 t2) t3 = appArgs t1 t2 <> [t3] + appArgs _ t3 = [t3] + + appFun :: Expr a -> Expr a + appFun (App _ t1 _) = appFun t1 + appFun res = res + +updateVarTy :: Ident -> PurusType -> Expr Ann -> Expr Ann +updateVarTy ident ty = itransform goVar (M.empty :: Context) + where + goVar :: forall x. x -> Expr Ann -> Expr Ann + goVar _ expr = case expr ^? _Var of + Just (ann,_,Qualified q@(BySourcePos _) varId) | varId == ident -> Var ann ty (Qualified q ident) + _ -> expr + +appType :: Expr a -> Expr a -> SourceType +appType fe ae = case stripQuantifiers funTy of + ([],ft) -> + let numArgs = length argTypes + in foldl1 function . drop numArgs . splitFunTyParts $ ft + (xs,ft) -> + let funArgs = funArgTypes ft + dict = mkInstanceMap M.empty xs argTypes funArgs + numArgs = length argTypes + in quantify + . foldl1 function + . drop numArgs + . splitFunTyParts + . replaceAllTypeVars (M.toList dict) + $ ft + where + (f,args) = appFunArgs fe ae + funTy = exprType f + argTypes = exprType <$> args + + mkInstanceMap :: Map Text SourceType -> [Text] -> [SourceType] -> [SourceType] -> Map Text SourceType + mkInstanceMap acc [] _ _ = acc + mkInstanceMap acc _ [] _ = acc + mkInstanceMap acc _ _ [] = acc + mkInstanceMap acc (var:vars) (mt:mts) (pt:pts) = case instantiates var mt pt of + Nothing -> mkInstanceMap acc [var] mts pts + <> mkInstanceMap M.empty vars (mt:mts) (pt:pts) + Just t -> mkInstanceMap (M.insert var t acc) vars (mt:mts) (pt:pts) + +stripQuantifiers :: SourceType -> ([Text],SourceType) +stripQuantifiers = first reverse . go [] + where + go :: [Text] -> SourceType -> ([Text],SourceType) + go acc (ForAll _ _ var _ inner _) = go (var:acc) inner + go acc other = (acc,other) + +-- | (a -> b -> c) -> [a,b,c] +splitFunTyParts :: Type a -> [Type a] +splitFunTyParts = \case + (a :-> b) -> a : splitFunTyParts b + t -> [t] + +-- | (a -> b -> c) -> [a,b] +-- +-- NOTE: Unsafe/partial +funArgTypes :: Type a -> [Type a] +funArgTypes = init . splitFunTyParts + +exprType :: Expr a -> PurusType +exprType = \case + Literal _ ty _ -> ty + Constructor _ ty _ _ _ -> ty + Accessor _ ty _ _ -> ty + ObjectUpdate _ ty _ _ _ -> ty + Abs _ ty _ _ -> ty + App _ t1 t2 -> appType t1 t2 + Var _ ty __ -> ty + Case _ ty _ _ -> ty + Let _ _ e -> exprType e diff --git a/src/Language/PureScript/Environment.hs b/src/Language/PureScript/Environment.hs index e1f857031..050be400f 100644 --- a/src/Language/PureScript/Environment.hs +++ b/src/Language/PureScript/Environment.hs @@ -1,10 +1,12 @@ +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# HLINT ignore "Redundant bracket" #-} module Language.PureScript.Environment where import Prelude import GHC.Generics (Generic) import Control.DeepSeq (NFData) -import Control.Monad (unless) +import Control.Monad (unless, void) import Codec.Serialise (Serialise) import Data.Aeson ((.=), (.:)) import Data.Aeson qualified as A @@ -20,13 +22,15 @@ import Data.Text (Text) import Data.Text qualified as T import Data.List.NonEmpty qualified as NEL -import Language.PureScript.AST.SourcePos (nullSourceAnn) +import Language.PureScript.AST.SourcePos (nullSourceAnn, pattern NullSourceAnn) import Language.PureScript.Crash (internalError) import Language.PureScript.Names (Ident, ProperName(..), ProperNameType(..), Qualified, QualifiedBy, coerceProperName) import Language.PureScript.Roles (Role(..)) import Language.PureScript.TypeClassDictionaries (NamedDict) import Language.PureScript.Types (SourceConstraint, SourceType, Type(..), TypeVarVisibility(..), eqType, srcTypeConstructor, freeTypeVariables) import Language.PureScript.Constants.Prim qualified as C +import Language.PureScript.Constants.Purus qualified as PLC +import Codec.CBOR.Write (toLazyByteString) -- | The @Environment@ defines all values and types which are currently in scope: data Environment = Environment @@ -99,9 +103,9 @@ instance A.ToJSON FunctionalDependency where , "determined" .= fdDetermined ] --- | The initial environment with no values and only the default javascript types defined +-- | The initial environment with only builtin PLC functions and Prim PureScript types defined initEnvironment :: Environment -initEnvironment = Environment M.empty allPrimTypes M.empty M.empty M.empty allPrimClasses +initEnvironment = Environment builtinFunctions allPrimTypes M.empty M.empty M.empty allPrimClasses -- | A constructor for TypeClassData that computes which type class arguments are fully determined -- and argument covering sets. @@ -361,6 +365,40 @@ tyForall var k ty = ForAll nullSourceAnn TypeVarInvisible var (Just k) ty Nothin function :: SourceType -> SourceType -> SourceType function = TypeApp nullSourceAnn . TypeApp nullSourceAnn tyFunction +purusFun :: Type a -> Type a -> Type () +purusFun = f . g + where + f x = TypeApp () x . void + g = TypeApp () tyFunctionNoAnn . void + tyFunctionNoAnn = TypeConstructor () C.Function + +-- This is borderline necessary +pattern (:->) :: Type a -> Type a -> Type a +pattern a :-> b <- + TypeApp _ + (TypeApp _ (TypeConstructor _ C.Function) a) + b + +pattern ArrayT :: Type a -> Type a +pattern ArrayT a <- + TypeApp _ (TypeConstructor _ C.Array) a + +arrayT :: SourceType -> SourceType +arrayT = TypeApp NullSourceAnn (TypeConstructor NullSourceAnn C.Array) + +pattern RecordT :: Type a -> Type a +pattern RecordT a <- + TypeApp _ (TypeConstructor _ C.Record) a + +mkRecordT :: SourceType -> SourceType +mkRecordT = TypeApp nullSourceAnn (TypeConstructor nullSourceAnn C.Record) + +getFunArgTy :: Type a -> Type a +getFunArgTy = \case + a :-> _ -> a + ForAll _ _ _ _ t _ -> getFunArgTy t + other -> other + -- To make reading the kind signatures below easier (-:>) :: SourceType -> SourceType -> SourceType (-:>) = function @@ -407,6 +445,8 @@ allPrimTypes = M.unions , primSymbolTypes , primIntTypes , primTypeErrorTypes + -- For the sake of simplicity I'm putting the builtins here as well + , builtinTypes ] primBooleanTypes :: M.Map (Qualified (ProperName 'TypeName)) (SourceType, TypeKind) @@ -685,3 +725,137 @@ unapplyKinds = go [] where | eqType fn tyFunction = go (k1 : kinds) k2 go kinds (ForAll _ _ _ _ k _) = go kinds k go kinds k = (reverse kinds, k) + +-- | +-- Plutus Data / Builtins: +-- We need to provide primitives for Data-encoded objects, +-- builtin functions, etc + +tyBuiltinData :: SourceType +tyBuiltinData = srcTypeConstructor PLC.BuiltinData + +tyAsData :: SourceType -> SourceType +tyAsData = TypeApp nullSourceAnn (srcTypeConstructor PLC.AsData) + +tyBuiltinPair :: SourceType -> SourceType -> SourceType +tyBuiltinPair a b = + TypeApp nullSourceAnn + (TypeApp nullSourceAnn (srcTypeConstructor PLC.BuiltinPair) + a) + b + +tyBuiltinList :: SourceType -> SourceType +tyBuiltinList = TypeApp nullSourceAnn (srcTypeConstructor PLC.BuiltinList) + +tyByteString :: SourceType +tyByteString = srcTypeConstructor PLC.BuiltinByteString + +tyUnit :: SourceType +tyUnit = srcTypeConstructor PLC.BuiltinUnit + +-- just for readability +(#@) :: Qualified Ident -> SourceType -> (Qualified Ident, SourceType) +f #@ t = (f,t) + +-- the kind is Type here. This is just to avoid potentially making a typo (and to make the manual function sigs more readable) +forallT :: Text -> (SourceType -> SourceType) -> SourceType +forallT txt f = tyForall txt kindType (f $ tyVar txt) +infixr 0 #@ + +builtinTypes :: M.Map (Qualified (ProperName 'TypeName)) (SourceType, TypeKind) +builtinTypes = M.fromList [ + (PLC.BuiltinData, (kindType, ExternData [])), + (PLC.BuiltinPair, (kindType -:> kindType -:> kindType, ExternData [Representational, Representational])), + (PLC.BuiltinList, (kindType -:> kindType, ExternData [Representational])), + (PLC.BuiltinByteString, (kindType, ExternData [])) + ] + +builtinFunctions :: M.Map (Qualified Ident) (SourceType, NameKind, NameVisibility) +builtinFunctions = builtinCxt <&> \x -> (x,Public,Defined) + +-- NOTE/REVIEW: I'm rendering all "Word8" types as tyInt for now. +-- I'm not sure whether that's correct +builtinCxt :: M.Map (Qualified Ident) SourceType +builtinCxt = M.fromList [ + -- Integers + PLC.I_addInteger #@ tyInt -:> tyInt -:> tyInt, + PLC.I_subtractInteger #@ tyInt -:> tyInt -:> tyInt, + PLC.I_multiplyInteger #@ tyInt -:> tyInt -:> tyInt, + PLC.I_divideInteger #@ tyInt -:> tyInt -:> tyInt, + PLC.I_quotientInteger #@ tyInt -:> tyInt -:> tyInt, + PLC.I_remainderInteger #@ tyInt -:> tyInt -:> tyInt, + PLC.I_modInteger #@ tyInt -:> tyInt -:> tyInt, + PLC.I_equalsInteger #@ tyInt -:> tyInt -:> tyBoolean, + PLC.I_lessThanInteger #@ tyInt -:> tyInt -:> tyBoolean, + + -- ByteStrings + PLC.I_appendByteString #@ tyByteString -:> tyByteString -:> tyByteString, + -- \/ Check the implications of the variant semantics for this (https://github.com/IntersectMBO/plutus/blob/973e03bbccbe3b860e2c8bf70c2f49418811a6ce/plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs#L1179-L1207) + PLC.I_consByteString #@ tyInt -:> tyByteString -:> tyByteString, + PLC.I_sliceByteString #@ tyInt -:> tyInt -:> tyByteString -:> tyByteString, + PLC.I_lengthOfByteString #@ tyByteString -:> tyInt, + PLC.I_indexByteString #@ tyByteString -:> tyInt -:> tyInt, + PLC.I_equalsByteString #@ tyByteString -:> tyByteString -:> tyBoolean, + PLC.I_lessThanByteString #@ tyByteString -:> tyByteString -:> tyBoolean, + PLC.I_lessThanEqualsByteString #@ tyByteString -:> tyByteString -:> tyBoolean, + + -- Cryptography + PLC.I_sha2_256 #@ tyByteString -:> tyByteString, + PLC.I_sha3_256 #@ tyByteString -:> tyByteString, + PLC.I_blake2b_256 #@ tyByteString -:> tyByteString, + PLC.I_verifyEd25519Signature #@ tyByteString -:> tyByteString -:> tyByteString -:> tyBoolean, + PLC.I_verifyEcdsaSecp256k1Signature #@ tyByteString -:> tyByteString -:> tyByteString -:> tyBoolean, + + -- Strings + PLC.I_appendString #@ tyString -:> tyString -:> tyString, + PLC.I_equalsString #@ tyString -:> tyString -:> tyBoolean, + PLC.I_encodeUtf8 #@ tyString -:> tyByteString, + PLC.I_decodeUtf8 #@ tyByteString -:> tyString, + + -- Bool + -- NOTE: Specializing this to "Type", which miiiight not be what we want depending on how we do the data encoding + PLC.I_ifThenElse #@ forallT "x" $ \x -> tyBoolean -:> x -:> x, + + -- Unit + PLC.I_chooseUnit #@ forallT "x" $ \x -> tyUnit -:> x -:> x, + + -- Tracing + PLC.I_trace #@ forallT "x" $ \x -> tyString -:> x, + + -- Pairs + PLC.I_fstPair #@ forallT "a" $ \a -> forallT "b" $ \b -> tyBuiltinPair a b -:> a, + PLC.I_sndPair #@ forallT "a" $ \a -> forallT "b" $ \b -> tyBuiltinPair a b -:> b, + + -- Lists + PLC.I_chooseList #@ forallT "a" $ \a -> forallT "b" $ \b -> tyBuiltinList a -:> b -:> b, + PLC.I_mkCons #@ forallT "a" $ \a -> a -:> tyBuiltinList a -:> tyBuiltinList a, + PLC.I_headList #@ forallT "a" $ \a -> tyBuiltinList a -:> a, + PLC.I_tailList #@ forallT "a" $ \a -> tyBuiltinList a -:> tyBuiltinList a, + PLC.I_nullList #@ forallT "a" $ \a -> tyBuiltinList a -:> tyBoolean, + + -- Data + -- Construction + PLC.I_chooseData #@ forallT "a" $ \a -> tyBuiltinData -:> a -:> a -:> a -:> a -:> a, + PLC.I_constrData #@ tyInt -:> tyBuiltinList tyBuiltinData -:> tyBuiltinData, + PLC.I_mapData #@ tyBuiltinList (tyBuiltinPair tyBuiltinData tyBuiltinData) -:> tyBuiltinData, + PLC.I_listData #@ tyBuiltinList tyBuiltinData -:> tyBuiltinData, + PLC.I_iData #@ tyInt -:> tyBuiltinData, + PLC.I_bData #@ tyByteString -:> tyBuiltinData, + -- Destruction + PLC.I_unConstrData #@ tyBuiltinData -:> tyBuiltinPair tyInt tyBuiltinData, + PLC.I_unMapData #@ tyBuiltinData -:> tyBuiltinList (tyBuiltinPair tyBuiltinData tyBuiltinData), + PLC.I_unListData #@ tyBuiltinData -:> tyBuiltinList tyBuiltinData, + PLC.I_unIData #@ tyBuiltinData -:> tyInt, + PLC.I_unBData #@ tyBuiltinData -:> tyByteString, + -- Data Misc + PLC.I_equalsData #@ tyBuiltinData -:> tyBuiltinData -:> tyBoolean, + PLC.I_serialiseData #@ tyBuiltinData -:> tyByteString, + + -- Misc constructors + PLC.I_mkPairData #@ tyBuiltinData -:> tyBuiltinData -:> tyBuiltinPair tyBuiltinData tyBuiltinData, + PLC.I_mkNilData #@ tyUnit -:> tyBuiltinList tyBuiltinData, + PLC.I_mkNilPairData #@ tyUnit -:> tyBuiltinList (tyBuiltinPair tyBuiltinData tyBuiltinData) + + -- TODO: the Bls12 crypto primfuns + -- NOTE: IntegerToByteString & ByteStringToInteger don't appear to be in the version of PlutusCore we have? + ] diff --git a/src/Language/PureScript/Ide/Rebuild.hs b/src/Language/PureScript/Ide/Rebuild.hs index ebc34339e..af6250731 100644 --- a/src/Language/PureScript/Ide/Rebuild.hs +++ b/src/Language/PureScript/Ide/Rebuild.hs @@ -16,7 +16,6 @@ import Data.Set qualified as S import Data.Time qualified as Time import Data.Text qualified as Text import Language.PureScript qualified as P -import Language.PureScript.Make (ffiCodegen') import Language.PureScript.Make.Cache (CacheInfo(..), normaliseForCache) import Language.PureScript.CST qualified as CST @@ -75,7 +74,6 @@ rebuildFile file actualFile codegenTargets runOpenBuild = do let modulePath = if pureRebuild then fp' else file foreigns <- P.inferForeignModules (M.singleton moduleName (Right modulePath)) let makeEnv = P.buildMakeActions outputDirectory filePathMap foreigns False - & (if pureRebuild then enableForeignCheck foreigns codegenTargets . shushCodegen else identity) & shushProgress -- Rebuild the single module using the cached externs (result, warnings) <- logPerf (labelTimespec "Rebuilding Module") $ @@ -122,12 +120,14 @@ updateCacheDb codegenTargets outputDirectory file actualFile moduleName = do let moduleCacheInfo = (normaliseForCache cwd (fromMaybe file actualFile), (dayZero, contentHash)) foreignCacheInfo <- + {- if S.member P.JS codegenTargets then do foreigns' <- P.inferForeignModules (M.singleton moduleName (Right (fromMaybe file actualFile))) for (M.lookup moduleName foreigns') \foreignPath -> do foreignHash <- P.hashFile foreignPath pure (normaliseForCache cwd foreignPath, (dayZero, foreignHash)) else + -} pure Nothing let cacheInfo = M.fromList (moduleCacheInfo : maybeToList foreignCacheInfo) @@ -184,17 +184,6 @@ shushProgress ma = shushCodegen :: Monad m => P.MakeActions m -> P.MakeActions m shushCodegen ma = ma { P.codegen = \_ _ _ -> pure () - , P.ffiCodegen = \_ -> pure () - } - --- | Enables foreign module check without actual codegen. -enableForeignCheck - :: M.Map P.ModuleName FilePath - -> S.Set P.CodegenTarget - -> P.MakeActions P.Make - -> P.MakeActions P.Make -enableForeignCheck foreigns codegenTargets ma = - ma { P.ffiCodegen = ffiCodegen' foreigns codegenTargets Nothing } -- | Returns a topologically sorted list of dependent ExternsFiles for the given diff --git a/src/Language/PureScript/Linter/Imports.hs b/src/Language/PureScript/Linter/Imports.hs index e8a2eb0f2..ee5f2146c 100644 --- a/src/Language/PureScript/Linter/Imports.hs +++ b/src/Language/PureScript/Linter/Imports.hs @@ -28,6 +28,7 @@ import Language.PureScript.Sugar.Names.Common (warnDuplicateRefs) import Language.PureScript.Sugar.Names.Env (Env, Exports(..), ImportRecord(..), Imports(..), envModuleExports, nullImports) import Language.PureScript.Sugar.Names.Imports (ImportDef, findImports) import Language.PureScript.Constants.Prim qualified as C +import Language.PureScript.Constants.Purus qualified as PLC -- | -- Map of module name to list of imported names from that module which have @@ -142,7 +143,7 @@ lintImports (Module _ _ mn mdecls (Just mexports)) env usedImps = do -- Checks whether a module is the Prim module - used to suppress any checks -- made, as Prim is always implicitly imported. isPrim :: ModuleName -> Bool - isPrim = (== C.M_Prim) + isPrim mx = (mx == C.M_Prim) || mx == PLC.M_Builtin -- Creates a map of virtual modules mapped to all the declarations that -- import to that module, with the corresponding source span, import type, diff --git a/src/Language/PureScript/Make.hs b/src/Language/PureScript/Make.hs index 8340d77ca..ffeedfe58 100644 --- a/src/Language/PureScript/Make.hs +++ b/src/Language/PureScript/Make.hs @@ -33,12 +33,12 @@ import Language.PureScript.AST (ErrorMessageHint(..), Module(..), SourceSpan(..) import Language.PureScript.Crash (internalError) import Language.PureScript.CST qualified as CST import Language.PureScript.Docs.Convert qualified as Docs -import Language.PureScript.Environment (initEnvironment) +import Language.PureScript.Environment (initEnvironment, Environment(..)) import Language.PureScript.Errors (MultipleErrors, SimpleErrorMessage(..), addHint, defaultPPEOptions, errorMessage', errorMessage'', prettyPrintMultipleErrors) import Language.PureScript.Externs (ExternsFile, applyExternsFileToEnvironment, moduleToExternsFile) import Language.PureScript.Linter (Name(..), lint, lintImports) import Language.PureScript.ModuleDependencies (DependencyDepth(..), moduleSignature, sortModules) -import Language.PureScript.Names (ModuleName, isBuiltinModuleName, runModuleName) +import Language.PureScript.Names (ModuleName, isBuiltinModuleName, runModuleName, showIdent, showQualified) import Language.PureScript.Renamer (renameInModule) import Language.PureScript.Sugar (Env, collapseBindingGroups, createBindingGroups, desugar, desugarCaseGuards, externsEnv, primEnv) import Language.PureScript.TypeChecker (CheckState(..), emptyCheckState, typeCheckModule) @@ -48,8 +48,16 @@ import Language.PureScript.Make.Cache qualified as Cache import Language.PureScript.Make.Actions as Actions import Language.PureScript.Make.Monad as Monad import Language.PureScript.CoreFn qualified as CF +import Language.PureScript.CoreFn qualified as CFT +import Language.PureScript.CoreFn.Pretty qualified as CFT import System.Directory (doesFileExist) import System.FilePath (replaceExtension) +import Prettyprinter.Util (putDocW) + +-- Temporary +import Debug.Trace (traceM) +import Language.PureScript.CoreFn.Pretty (ppType) +import Language.PureScript.CoreFn.Desugar.Utils (pTrace) -- | Rebuild a single module. -- @@ -90,17 +98,17 @@ rebuildModuleWithIndex MakeActions{..} exEnv externs m@(Module _ _ moduleName _ withPrim = importPrim m lint withPrim - ((Module ss coms _ elaborated exps, env'), nextVar) <- runSupplyT 0 $ do + ((Module ss coms _ elaborated exps, env', chkSt), nextVar) <- runSupplyT 0 $ do (desugared, (exEnv', usedImports)) <- runStateT (desugar externs withPrim) (exEnv, mempty) let modulesExports = (\(_, _, exports) -> exports) <$> exEnv' - (checked, CheckState{..}) <- runStateT (typeCheckModule modulesExports desugared) $ emptyCheckState env + (checked, chkSt@CheckState{..}) <- runStateT (typeCheckModule modulesExports desugared) $ emptyCheckState env let usedImports' = foldl' (flip $ \(fromModuleName, newtypeCtorName) -> M.alter (Just . (fmap DctorName newtypeCtorName :) . fold) fromModuleName) usedImports checkConstructorImportsForCoercible -- Imports cannot be linted before type checking because we need to -- known which newtype constructors are used to solve Coercible -- constraints in order to not report them as unused. censor (addHint (ErrorInModule moduleName)) $ lintImports checked exEnv' usedImports' - return (checked, checkEnv) + return (checked, checkEnv, chkSt) -- desugar case declarations *after* type- and exhaustiveness checking -- since pattern guards introduces cases which the exhaustiveness checker @@ -109,12 +117,19 @@ rebuildModuleWithIndex MakeActions{..} exEnv externs m@(Module _ _ moduleName _ desugarCaseGuards elaborated regrouped <- createBindingGroups moduleName . collapseBindingGroups $ deguarded + let mod' = Module ss coms moduleName regrouped exps - corefn = CF.moduleToCoreFn env' mod' - (optimized, nextVar'') = runSupply nextVar' $ CF.optimizeCoreFn corefn + traceM $ "PURUS START HERE: " <> T.unpack (runModuleName moduleName) + -- pTrace regrouped + -- pTrace exps + ((coreFn,chkSt'),nextVar'') <- runSupplyT nextVar' $ runStateT (CFT.moduleToCoreFn mod') chkSt -- (emptyCheckState env') + + traceM . T.unpack $ CFT.prettyModuleTxt coreFn + let corefn = coreFn + (optimized, nextVar''') = runSupply nextVar'' $ CF.optimizeCoreFn corefn (renamedIdents, renamed) = renameInModule optimized exts = moduleToExternsFile mod' env' renamedIdents - ffiCodegen renamed + --pTrace exts -- It may seem more obvious to write `docs <- Docs.convertModule m env' here, -- but I have not done so for two reasons: @@ -129,8 +144,20 @@ rebuildModuleWithIndex MakeActions{..} exEnv externs m@(Module _ _ moduleName _ ++ "; details:\n" ++ prettyPrintMultipleErrors defaultPPEOptions errs Right d -> d - evalSupplyT nextVar'' $ codegen renamed docs exts + evalSupplyT nextVar''' $ codegen renamed docs exts return exts + where + prettyEnv :: Environment -> String + prettyEnv Environment{..} = M.foldlWithKey' goPretty "" names + where + goPretty acc ident (ty,_,_) = + acc + <> "\n" + <> T.unpack (showQualified showIdent ident) + <> " :: " + <> ppType 10 ty + + -- | Compiles in "make" mode, compiling each module separately to a @.js@ file and an @externs.cbor@ file. -- @@ -148,7 +175,7 @@ make ma@MakeActions{..} ms = do (buildPlan, newCacheDb) <- BuildPlan.construct ma cacheDb (sorted, graph) - let toBeRebuilt = filter (BuildPlan.needsRebuild buildPlan . getModuleName . CST.resPartial) sorted + let toBeRebuilt = sorted -- filter (BuildPlan.needsRebuild buildPlan . getModuleName . CST.resPartial) sorted let totalModuleCount = length toBeRebuilt for_ toBeRebuilt $ \m -> fork $ do let moduleName = getModuleName . CST.resPartial $ m diff --git a/src/Language/PureScript/Make/Actions.hs b/src/Language/PureScript/Make/Actions.hs index f138327c8..184b43dff 100644 --- a/src/Language/PureScript/Make/Actions.hs +++ b/src/Language/PureScript/Make/Actions.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE TypeApplications #-} module Language.PureScript.Make.Actions ( MakeActions(..) , RebuildPolicy(..) @@ -8,7 +9,6 @@ module Language.PureScript.Make.Actions , cacheDbFile , readCacheDb' , writeCacheDb' - , ffiCodegen' ) where import Prelude @@ -20,26 +20,26 @@ import Control.Monad.Reader (asks) import Control.Monad.Supply (SupplyT) import Control.Monad.Trans.Class (MonadTrans(..)) import Control.Monad.Writer.Class (MonadWriter(..)) -import Data.Aeson (Value(String), (.=), object) +import Data.Aeson (Value(String), (.=), object, decode, encode, Result (..), fromJSON) import Data.Bifunctor (bimap, first) import Data.Either (partitionEithers) import Data.Foldable (for_) import Data.List.NonEmpty qualified as NEL import Data.Map qualified as M -import Data.Maybe (fromMaybe, maybeToList) +import Data.Maybe (fromMaybe, maybeToList, fromJust) import Data.Set qualified as S import Data.Text qualified as T import Data.Text.IO qualified as TIO import Data.Text.Encoding qualified as TE import Data.Time.Clock (UTCTime) -import Data.Version (showVersion) +import Data.Version (showVersion, makeVersion) import Language.JavaScript.Parser qualified as JS import Language.PureScript.AST (SourcePos(..)) import Language.PureScript.Bundle qualified as Bundle -import Language.PureScript.CodeGen.JS qualified as J -import Language.PureScript.CodeGen.JS.Printer (prettyPrintJS, prettyPrintJSWithSourceMaps) +import Language.PureScript.CodeGen.UPLC qualified as PC import Language.PureScript.CoreFn qualified as CF import Language.PureScript.CoreFn.ToJSON qualified as CFJ +import Language.PureScript.CoreFn.FromJSON () import Language.PureScript.Crash (internalError) import Language.PureScript.CST qualified as CST import Language.PureScript.Docs.Prim qualified as Docs.Prim @@ -57,7 +57,10 @@ import SourceMap.Types (Mapping(..), Pos(..), SourceMapping(..)) import System.Directory (getCurrentDirectory) import System.FilePath ((), makeRelative, splitPath, normalise, splitDirectories) import System.FilePath.Posix qualified as Posix -import System.IO (stderr) +import System.IO (stderr, withFile, IOMode(WriteMode)) +import Language.PureScript.CoreFn.ToJSON (moduleToJSON) +import Language.PureScript.CoreFn.Pretty (writeModule) + -- | Determines when to rebuild a module data RebuildPolicy @@ -112,10 +115,8 @@ data MakeActions m = MakeActions , readExterns :: ModuleName -> m (FilePath, Maybe ExternsFile) -- ^ Read the externs file for a module as a string and also return the actual -- path for the file. - , codegen :: CF.Module CF.Ann -> Docs.Module -> ExternsFile -> SupplyT m () + , codegen :: CF.Module (CF.Bind CF.Ann) CF.Ann -> Docs.Module -> ExternsFile -> SupplyT m () -- ^ Run the code generator for the module and write any required output files. - , ffiCodegen :: CF.Module CF.Ann -> m () - -- ^ Check ffi and print it in the output directory. , progress :: ProgressMessage -> m () -- ^ Respond to a progress update. , readCacheDb :: m CacheDb @@ -174,25 +175,29 @@ buildMakeActions -- ^ Generate a prefix comment? -> MakeActions Make buildMakeActions outputDir filePathMap foreigns usePrefix = - MakeActions getInputTimestampsAndHashes getOutputTimestamp readExterns codegen ffiCodegen progress readCacheDb writeCacheDb writePackageJson outputPrimDocs + MakeActions getInputTimestampsAndHashes getOutputTimestamp readExterns codegen progress readCacheDb writeCacheDb writePackageJson outputPrimDocs where getInputTimestampsAndHashes :: ModuleName -> Make (Either RebuildPolicy (M.Map FilePath (UTCTime, Make ContentHash))) getInputTimestampsAndHashes mn = do - let path = fromMaybe (internalError "Module has no filename in 'make'") $ M.lookup mn filePathMap - case path of - Left policy -> - return (Left policy) - Right filePath -> do - cwd <- makeIO "Getting the current directory" getCurrentDirectory - let inputPaths = map (normaliseForCache cwd) (filePath : maybeToList (M.lookup mn foreigns)) - getInfo fp = do - ts <- getTimestamp fp - return (ts, hashFile fp) - pathsWithInfo <- traverse (\fp -> (fp,) <$> getInfo fp) inputPaths - return $ Right $ M.fromList pathsWithInfo + codegenTargets <- asks optionsCodegenTargets + if CheckCoreFn `S.member` codegenTargets + then pure (Left RebuildAlways) + else do + let path = fromMaybe (internalError "Module has no filename in 'make'") $ M.lookup mn filePathMap + case path of + Left policy -> + return (Left policy) + Right filePath -> do + cwd <- makeIO "Getting the current directory" getCurrentDirectory + let inputPaths = map (normaliseForCache cwd) (filePath : maybeToList (M.lookup mn foreigns)) + getInfo fp = do + ts <- getTimestamp fp + return (ts, hashFile fp) + pathsWithInfo <- traverse (\fp -> (fp,) <$> getInfo fp) inputPaths + return $ Right $ M.fromList pathsWithInfo outputFilename :: ModuleName -> String -> FilePath outputFilename mn fn = @@ -201,10 +206,9 @@ buildMakeActions outputDir filePathMap foreigns usePrefix = targetFilename :: ModuleName -> CodegenTarget -> FilePath targetFilename mn = \case - JS -> outputFilename mn "index.js" - JSSourceMap -> outputFilename mn "index.js.map" - CoreFn -> outputFilename mn "corefn.json" Docs -> outputFilename mn "docs.json" + CoreFn -> outputFilename mn "index.cfn" + CheckCoreFn -> outputFilename mn "index.cfn" getOutputTimestamp :: ModuleName -> Make (Maybe UTCTime) getOutputTimestamp mn = do @@ -245,43 +249,35 @@ buildMakeActions outputDir filePathMap foreigns usePrefix = when (S.member Docs codegenTargets) $ for_ Docs.Prim.primModules $ \docsMod@Docs.Module{..} -> writeJSONFile (outputFilename modName "docs.json") docsMod - codegen :: CF.Module CF.Ann -> Docs.Module -> ExternsFile -> SupplyT Make () + codegen :: CF.Module (CF.Bind CF.Ann) CF.Ann -> Docs.Module -> ExternsFile -> SupplyT Make () codegen m docs exts = do let mn = CF.moduleName m lift $ writeCborFile (outputFilename mn externsFileName) exts codegenTargets <- lift $ asks optionsCodegenTargets - when (S.member CoreFn codegenTargets) $ do - let coreFnFile = targetFilename mn CoreFn + {- -when (S.member UPLC codegenTargets) $ do + let coreFnFile = targetFilename mn UPLC json = CFJ.moduleToJSON Paths.version m lift $ writeJSONFile coreFnFile json - when (S.member JS codegenTargets) $ do - foreignInclude <- case mn `M.lookup` foreigns of - Just _ - | not $ requiresForeign m -> do - return Nothing - | otherwise -> do - return $ Just "./foreign.js" - Nothing | requiresForeign m -> throwError . errorMessage' (CF.moduleSourceSpan m) $ MissingFFIModule mn - | otherwise -> return Nothing - rawJs <- J.moduleToJs m foreignInclude - dir <- lift $ makeIO "get the current directory" getCurrentDirectory - let sourceMaps = S.member JSSourceMap codegenTargets - (pjs, mappings) = if sourceMaps then prettyPrintJSWithSourceMaps rawJs else (prettyPrintJS rawJs, []) - jsFile = targetFilename mn JS - mapFile = targetFilename mn JSSourceMap - prefix = ["Generated by purs version " <> T.pack (showVersion Paths.version) | usePrefix] - js = T.unlines $ map ("// " <>) prefix ++ [pjs] - mapRef = if sourceMaps then "//# sourceMappingURL=index.js.map\n" else "" - lift $ do - writeTextFile jsFile (TE.encodeUtf8 $ js <> mapRef) - when sourceMaps $ genSourceMap dir mapFile (length prefix) mappings + -} when (S.member Docs codegenTargets) $ do lift $ writeJSONFile (outputFilename mn "docs.json") docs - - ffiCodegen :: CF.Module CF.Ann -> Make () - ffiCodegen m = do - codegenTargets <- asks optionsCodegenTargets - ffiCodegen' foreigns codegenTargets (Just outputFilename) m + when (S.member CoreFn codegenTargets) $ do + let targetFile = (targetFilename mn CoreFn) + lift $ writeJSONFile targetFile (moduleToJSON (makeVersion [0,0,1]) m) + lift $ makeIO "write pretty core" $ withFile (targetFile <> ".pretty") WriteMode $ \handle -> + writeModule handle m + when (S.member CheckCoreFn codegenTargets) $ do + let mn' = T.unpack (runModuleName mn) + mabOldModule <- lift $ readJSONFile (targetFilename mn CoreFn) + case mabOldModule of + Nothing -> error "Cannot check CoreFn output - could not parse JSON serialization of old module" + Just oldM -> do + lift $ makeIO "print golden result" $ putStrLn $ mn' <> ": old module == new module: " <> show (m == oldM) + where + jsonRoundTrip :: CF.Module (CF.Bind CF.Ann) CF.Ann -> CF.Module (CF.Bind CF.Ann) CF.Ann + jsonRoundTrip mdl = case fromJSON $ moduleToJSON (makeVersion [0,0,1]) mdl of + Error str -> error str + Success a -> a genSourceMap :: String -> String -> Int -> [SMap] -> Make () genSourceMap dir mapFile extraLines mappings = do @@ -310,7 +306,7 @@ buildMakeActions outputDir filePathMap foreigns usePrefix = normalizeSMPath :: FilePath -> FilePath normalizeSMPath = Posix.joinPath . splitDirectories - requiresForeign :: CF.Module a -> Bool + requiresForeign :: CF.Module (CF.Bind a) a -> Bool requiresForeign = not . null . CF.moduleForeign progress :: ProgressMessage -> Make () @@ -329,7 +325,7 @@ data ForeignModuleType = ESModule | CJSModule deriving (Show) -- | Check that the declarations in a given PureScript module match with those -- in its corresponding foreign module. -checkForeignDecls :: CF.Module ann -> FilePath -> Make (Either MultipleErrors (ForeignModuleType, S.Set Ident)) +checkForeignDecls :: CF.Module (CF.Bind ann) ann -> FilePath -> Make (Either MultipleErrors (ForeignModuleType, S.Set Ident)) checkForeignDecls m path = do jsStr <- T.unpack <$> readTextFile path @@ -423,33 +419,3 @@ checkForeignDecls m path = do . CST.runTokenParser CST.parseIdent . CST.lex $ T.pack str - --- | FFI check and codegen action. --- If path maker is supplied copies foreign module to the output. -ffiCodegen' - :: M.Map ModuleName FilePath - -> S.Set CodegenTarget - -> Maybe (ModuleName -> String -> FilePath) - -> CF.Module CF.Ann - -> Make () -ffiCodegen' foreigns codegenTargets makeOutputPath m = do - when (S.member JS codegenTargets) $ do - let mn = CF.moduleName m - case mn `M.lookup` foreigns of - Just path - | not $ requiresForeign m -> - tell $ errorMessage' (CF.moduleSourceSpan m) $ UnnecessaryFFIModule mn path - | otherwise -> do - checkResult <- checkForeignDecls m path - case checkResult of - Left _ -> copyForeign path mn - Right (ESModule, _) -> copyForeign path mn - Right (CJSModule, _) -> do - throwError $ errorMessage' (CF.moduleSourceSpan m) $ DeprecatedFFICommonJSModule mn path - Nothing | requiresForeign m -> throwError . errorMessage' (CF.moduleSourceSpan m) $ MissingFFIModule mn - | otherwise -> return () - where - requiresForeign = not . null . CF.moduleForeign - - copyForeign path mn = - for_ makeOutputPath (\outputFilename -> copyFile path (outputFilename mn "foreign.js")) diff --git a/src/Language/PureScript/Names.hs b/src/Language/PureScript/Names.hs index e5df3610b..00df17612 100644 --- a/src/Language/PureScript/Names.hs +++ b/src/Language/PureScript/Names.hs @@ -1,5 +1,5 @@ {-# LANGUAGE TemplateHaskell #-} - +{-# LANGUAGE GeneralizedNewtypeDeriving, DerivingVia #-} -- | -- Data types for names -- @@ -157,6 +157,7 @@ coerceOpName = OpName . runOpName -- newtype ProperName (a :: ProperNameType) = ProperName { runProperName :: Text } deriving (Show, Eq, Ord, Generic) + deriving newtype (ToJSONKey,FromJSONKey) instance NFData (ProperName a) instance Serialise (ProperName a) @@ -210,6 +211,9 @@ data QualifiedBy pattern ByNullSourcePos :: QualifiedBy pattern ByNullSourcePos = BySourcePos (SourcePos 0 0) +pattern ByThisModuleName :: Text -> QualifiedBy +pattern ByThisModuleName t = ByModuleName (ModuleName t) + instance NFData QualifiedBy instance Serialise QualifiedBy diff --git a/src/Language/PureScript/Options.hs b/src/Language/PureScript/Options.hs index d94d344cf..ae4131559 100644 --- a/src/Language/PureScript/Options.hs +++ b/src/Language/PureScript/Options.hs @@ -18,15 +18,21 @@ data Options = Options -- Default make options defaultOptions :: Options -defaultOptions = Options False False (S.singleton JS) +defaultOptions = Options False False (S.singleton CoreFn) -data CodegenTarget = JS | JSSourceMap | CoreFn | Docs +data CodegenTarget + = Docs + | CoreFn + {- N.B. We need a compilation mode that tests for changes from existing serialized CoreFn. + This is the easiest way to implement that (though maybe we should do something else for the final version) + -} + | CheckCoreFn deriving (Eq, Ord, Show) codegenTargets :: Map String CodegenTarget codegenTargets = Map.fromList - [ ("js", JS) - , ("sourcemaps", JSSourceMap) - , ("corefn", CoreFn) + [ ("coreFn", CoreFn) + , ("checkCoreFn", CheckCoreFn) + -- , ("corefn", CoreFn) , ("docs", Docs) ] diff --git a/src/Language/PureScript/Pretty/Types.hs b/src/Language/PureScript/Pretty/Types.hs index 20de0ed9e..fafc3a2fe 100644 --- a/src/Language/PureScript/Pretty/Types.hs +++ b/src/Language/PureScript/Pretty/Types.hs @@ -17,6 +17,7 @@ module Language.PureScript.Pretty.Types ) where import Prelude hiding ((<>)) +import Prelude qualified as P import Control.Arrow ((<+>)) import Control.Lens (_2, (%~)) @@ -36,6 +37,7 @@ import Language.PureScript.Label (Label(..)) import Text.PrettyPrint.Boxes (Box(..), hcat, hsep, left, moveRight, nullBox, render, text, top, vcat, (<>)) + data PrettyPrintType = PPTUnknown Int | PPTypeVar Text (Maybe Text) @@ -56,6 +58,7 @@ data PrettyPrintType | PPRecord [(Label, PrettyPrintType)] (Maybe PrettyPrintType) | PPRow [(Label, PrettyPrintType)] (Maybe PrettyPrintType) | PPTruncated + deriving (Show) type PrettyPrintConstraint = (Qualified (ProperName 'ClassName), [PrettyPrintType], [PrettyPrintType]) @@ -75,7 +78,7 @@ convertPrettyPrintType = go -- Guard the remaining "complex" type atoms on the current depth value. The -- prior constructors can all be printed simply so it's not really helpful to -- truncate them. - go d _ | d < 0 = PPTruncated + -- go d _ | d < 0 = PPTruncated go d (ConstrainedType _ (Constraint _ cls kargs args _) ty) = PPConstrainedType (cls, go (d-1) <$> kargs, go (d-1) <$> args) (go d ty) go d (KindedType _ ty k) = PPKindedType (go (d-1) ty) (go (d-1) k) go d (BinaryNoParensType _ ty1 ty2 ty3) = PPBinaryNoParensType (go (d-1) ty1) (go (d-1) ty2) (go (d-1) ty3) @@ -123,7 +126,7 @@ prettyPrintRowWith tro open close labels rest = ([], Nothing) -> if troRowAsDiff tro then text [ open, ' ' ] <> text "..." <> text [ ' ', close ] else text [ open, close ] ([], Just _) -> - text [ open, ' ' ] <> tailToPs rest <> text [ ' ', close ] + text [ open {-, ' ' -}] <> tailToPs rest <> text [ ' ' {-, close -}] _ -> vcat left $ zipWith (\(nm, ty) i -> nameAndTypeToPs (if i == 0 then open else ',') nm ty) labels [0 :: Int ..] ++ @@ -192,7 +195,7 @@ matchTypeAtom tro@TypeRenderOptions{troSuggesting = suggesting} = | suggesting = Just $ text "_" | otherwise = Just $ text $ 't' : show u match (PPSkolem name s) - | suggesting = Just $ text $ T.unpack name + | suggesting = Just $ text $ "skolem[" P.<> show s P.<> "]=" P.<> T.unpack name | otherwise = Just $ text $ T.unpack name ++ show s match (PPRecord labels tail_) = Just $ prettyPrintRowWith tro '{' '}' labels tail_ match (PPRow labels tail_) = Just $ prettyPrintRowWith tro '(' ')' labels tail_ diff --git a/src/Language/PureScript/Pretty/Values.hs b/src/Language/PureScript/Pretty/Values.hs index 4d5a5ec60..f8bca7e49 100644 --- a/src/Language/PureScript/Pretty/Values.hs +++ b/src/Language/PureScript/Pretty/Values.hs @@ -5,6 +5,7 @@ module Language.PureScript.Pretty.Values ( prettyPrintValue , prettyPrintBinder , prettyPrintBinderAtom + , renderValue ) where import Prelude hiding ((<>)) @@ -24,7 +25,7 @@ import Language.PureScript.Pretty.Types (typeAsBox, typeAtomAsBox, prettyPrintOb import Language.PureScript.Types (Constraint(..)) import Language.PureScript.PSString (PSString, prettyPrintString) -import Text.PrettyPrint.Boxes (Box, left, moveRight, text, vcat, vsep, (//), (<>)) +import Text.PrettyPrint.Boxes (Box, left, moveRight, text, vcat, vsep, (//), (<>), render) -- TODO(Christoph): remove T.unpack s @@ -50,6 +51,10 @@ prettyPrintObject d = list '{' '}' prettyPrintObjectProperty prettyPrintUpdateEntry :: Int -> PSString -> Expr -> Box prettyPrintUpdateEntry d key val = textT (prettyPrintObjectKey key) <> text " = " <> prettyPrintValue (d - 1) val + +renderValue :: Int -> Expr -> String +renderValue d e = render (prettyPrintValue d e) + -- | Pretty-print an expression prettyPrintValue :: Int -> Expr -> Box prettyPrintValue d _ | d < 0 = text "..." diff --git a/src/Language/PureScript/Renamer.hs b/src/Language/PureScript/Renamer.hs index a54e39f1e..1402e86b2 100644 --- a/src/Language/PureScript/Renamer.hs +++ b/src/Language/PureScript/Renamer.hs @@ -100,8 +100,8 @@ lookupIdent name = do -- identifiers in the top-level scope, so that they can be renamed in the -- externs files as well. -- -renameInModule :: Module Ann -> (M.Map Ident Ident, Module Ann) -renameInModule m@(Module _ _ _ _ _ exports _ foreigns decls) = (rsBoundNames, m { moduleExports, moduleDecls }) +renameInModule :: Module (Bind Ann) Ann -> (M.Map Ident Ident, Module (Bind Ann) Ann) +renameInModule m@(Module _ _ _ _ _ exports _ foreigns decls _) = (rsBoundNames, m { moduleExports, moduleDecls }) where ((moduleDecls, moduleExports), RenameState{..}) = runRename foreigns $ (,) <$> renameInDecls decls <*> traverse lookupIdent exports @@ -161,26 +161,26 @@ renameInDecls = -- Renames within a value. -- renameInValue :: Expr Ann -> Rename (Expr Ann) -renameInValue (Literal ann l) = - Literal ann <$> renameInLiteral renameInValue l +renameInValue (Literal ann t l) = + Literal ann t <$> renameInLiteral renameInValue l renameInValue c@Constructor{} = return c -renameInValue (Accessor ann prop v) = - Accessor ann prop <$> renameInValue v -renameInValue (ObjectUpdate ann obj copy vs) = - (\obj' -> ObjectUpdate ann obj' copy) <$> renameInValue obj <*> traverse (\(name, v) -> (name, ) <$> renameInValue v) vs -renameInValue (Abs ann name v) = - newScope $ Abs ann <$> updateScope name <*> renameInValue v +renameInValue (Accessor ann t prop v) = + Accessor ann t prop <$> renameInValue v +renameInValue (ObjectUpdate ann t obj copy vs) = + (\obj' -> ObjectUpdate ann t obj' copy) <$> renameInValue obj <*> traverse (\(name, v) -> (name, ) <$> renameInValue v) vs +renameInValue (Abs ann t name v) = + newScope $ Abs ann t <$> updateScope name <*> renameInValue v renameInValue (App ann v1 v2) = App ann <$> renameInValue v1 <*> renameInValue v2 -renameInValue (Var ann (Qualified qb name)) | isBySourcePos qb || not (isPlainIdent name) = +renameInValue (Var ann t (Qualified qb name)) | isBySourcePos qb || not (isPlainIdent name) = -- This should only rename identifiers local to the current module: either -- they aren't qualified, or they are but they have a name that should not -- have appeared in a module's externs, so they must be from this module's -- top-level scope. - Var ann . Qualified qb <$> lookupIdent name + Var ann t . Qualified qb <$> lookupIdent name renameInValue v@Var{} = return v -renameInValue (Case ann vs alts) = - newScope $ Case ann <$> traverse renameInValue vs <*> traverse renameInCaseAlternative alts +renameInValue (Case ann t vs alts) = + newScope $ Case ann t <$> traverse renameInValue vs <*> traverse renameInCaseAlternative alts renameInValue (Let ann ds v) = newScope $ Let ann <$> renameInDecls ds <*> renameInValue v diff --git a/src/Language/PureScript/Sugar.hs b/src/Language/PureScript/Sugar.hs index 4d713d541..fdaf44fd8 100644 --- a/src/Language/PureScript/Sugar.hs +++ b/src/Language/PureScript/Sugar.hs @@ -73,3 +73,4 @@ desugar externs = >=> deriveInstances >=> desugarTypeClasses externs >=> createBindingGroupsModule + diff --git a/src/Language/PureScript/Sugar/CaseDeclarations.hs b/src/Language/PureScript/Sugar/CaseDeclarations.hs index bcae76771..1d2d0e4c8 100644 --- a/src/Language/PureScript/Sugar/CaseDeclarations.hs +++ b/src/Language/PureScript/Sugar/CaseDeclarations.hs @@ -6,6 +6,7 @@ module Language.PureScript.Sugar.CaseDeclarations ( desugarCases , desugarCasesModule , desugarCaseGuards + , desugarGuardedExprs ) where import Prelude @@ -16,15 +17,17 @@ import Data.Maybe (catMaybes, mapMaybe) import Control.Monad ((<=<), forM, replicateM, join, unless) import Control.Monad.Error.Class (MonadError(..)) -import Control.Monad.Supply.Class (MonadSupply) +import Control.Monad.Supply.Class (MonadSupply, freshName) import Language.PureScript.AST import Language.PureScript.Crash (internalError) -import Language.PureScript.Environment (NameKind(..)) +import Language.PureScript.Environment (NameKind(..), function) import Language.PureScript.Errors (ErrorMessage(..), MultipleErrors(..), SimpleErrorMessage(..), addHint, errorMessage', parU, rethrow, withPosition) -import Language.PureScript.Names (pattern ByNullSourcePos, Ident, Qualified(..), freshIdent') +import Language.PureScript.Names (pattern ByNullSourcePos, Ident(..), Qualified(..), freshIdent') import Language.PureScript.TypeChecker.Monad (guardWith) +import Debug.Trace +import Language.PureScript.Types (SourceType, Type (TypeVar), quantify) -- | -- Replace all top-level binders in a module with case expressions. -- @@ -63,8 +66,9 @@ desugarGuardedExprs ss (Case scrut alternatives) -- we may evaluate the scrutinee more than once when a guard occurs. -- We bind the scrutinee to Vars here to mitigate this case. (scrut', scrut_decls) <- unzip <$> forM scrut (\e -> do + let mkTyped ex = TypedValue False ex (unsafeExprType e) scrut_id <- freshIdent' - pure ( Var ss (Qualified ByNullSourcePos scrut_id) + pure ( mkTyped $ Var ss (Qualified ByNullSourcePos scrut_id) , ValueDecl (ss, []) scrut_id Private [] [MkUnguarded e] ) ) @@ -78,6 +82,8 @@ desugarGuardedExprs ss (Case scrut alternatives) isTrivialExpr (TypedValue _ e _) = isTrivialExpr e isTrivialExpr _ = False + + desugarGuardedExprs ss (Case scrut alternatives) = let -- Alternatives which do not have guards are @@ -148,9 +154,11 @@ desugarGuardedExprs ss (Case scrut alternatives) = -- Special case: CoreFn understands single condition guards on -- binders right hand side. desugarAlternatives (CaseAlternative ab ge : as) - | not (null cond_guards) = + -- NOTE/REVIEW: Not sure about removing this + {-| not (null cond_guards) = (CaseAlternative ab cond_guards :) <$> desugarGuardedAlternative ab rest as + -} | otherwise = desugarGuardedAlternative ab ge as where (cond_guards, rest) = span isSingleCondGuard ge @@ -174,6 +182,10 @@ desugarGuardedExprs ss (Case scrut alternatives) = alt_fail' n | all isIrrefutable vb = [] | otherwise = alt_fail n + eTy = unsafeExprType e + + mkType ex = TypedValue False ex eTy + -- we are here: -- @@ -184,7 +196,7 @@ desugarGuardedExprs ss (Case scrut alternatives) = -- in case scrut of -- we are here -- ... -- - in Case scrut + in mkType $ Case scrut (CaseAlternative vb [MkUnguarded (desugarGuard gs e alt_fail)] : alt_fail' (length scrut)) @@ -224,16 +236,23 @@ desugarGuardedExprs ss (Case scrut alternatives) = rem_case_id <- freshIdent' unused_binder <- freshIdent' + freshTyVar <- freshName + let + remTy = quantify $ function (TypeVar (ss,[]) freshTyVar) (unsafeExprType desugared) + mkType e = TypedValue False e remTy + goto_rem_case :: Expr - goto_rem_case = Var ss (Qualified ByNullSourcePos rem_case_id) + goto_rem_case = mkType (Var ss (Qualified ByNullSourcePos rem_case_id)) `App` Literal ss (BooleanLiteral True) alt_fail :: Int -> [CaseAlternative] alt_fail n = [CaseAlternative (replicate n NullBinder) [MkUnguarded goto_rem_case]] + + pure $ Let FromLet [ ValueDecl (ss, []) rem_case_id Private [] - [MkUnguarded (Abs (VarBinder ss unused_binder) desugared)] + [MkUnguarded $ mkType (Abs (VarBinder ss unused_binder ) desugared)] ] (mk_body alt_fail) | otherwise @@ -417,3 +436,7 @@ makeCaseDeclaration ss ident alternatives = do | a == b = Just a | otherwise = Nothing resolveName _ _ = Nothing + +unsafeExprType :: Expr -> SourceType +unsafeExprType (TypedValue _ _ t) = t +unsafeExprType other = error $ "INTERNAL ERROR: Expected a TypedValue during case desugaring but got: " <> show other diff --git a/src/Language/PureScript/Sugar/Names/Env.hs b/src/Language/PureScript/Sugar/Names/Env.hs index 2ab8b00d5..e94e813c2 100644 --- a/src/Language/PureScript/Sugar/Names/Env.hs +++ b/src/Language/PureScript/Sugar/Names/Env.hs @@ -38,6 +38,7 @@ import Language.PureScript.Crash (internalError) import Language.PureScript.Environment import Language.PureScript.Errors (MultipleErrors, SimpleErrorMessage(..), errorMessage, errorMessage') import Language.PureScript.Names (Ident, ModuleName, Name(..), OpName, OpNameType(..), ProperName, ProperNameType(..), Qualified(..), QualifiedBy(..), coerceProperName, disqualify, getQual) +import Language.PureScript.Constants.Purus qualified as PLC -- | -- The details for an import: the name of the thing that is being imported @@ -157,6 +158,12 @@ nullExports = Exports M.empty M.empty M.empty M.empty M.empty -- type Env = M.Map ModuleName (SourceSpan, Imports, Exports) +-- | +-- The exported types and primitive values from the Builtin module +-- +builtinExports :: Exports +builtinExports = mkBuiltinExports builtinTypes builtinFunctions + -- | -- Extracts the 'Exports' from an 'Env' value. -- @@ -216,6 +223,19 @@ primIntExports = mkPrimExports primIntTypes primIntClasses primTypeErrorExports :: Exports primTypeErrorExports = mkPrimExports primTypeErrorTypes primTypeErrorClasses +-- | +-- Create a set of exports for a Purus Builtins module +-- +mkBuiltinExports + :: M.Map (Qualified (ProperName 'TypeName)) a + -> M.Map (Qualified Ident) b + -> Exports +mkBuiltinExports ts vs = + nullExports + { exportedTypes = M.fromList $ mkTypeEntry <$> M.keys ts, + exportedValues = M.fromList $ mkValueEntry <$> M.keys vs + } + -- | -- Create a set of exports for a Prim module. -- @@ -228,25 +248,31 @@ mkPrimExports ts cs = { exportedTypes = M.fromList $ mkTypeEntry `map` M.keys ts , exportedTypeClasses = M.fromList $ mkClassEntry `map` M.keys cs } - where - mkTypeEntry (Qualified (ByModuleName mn) name) = (name, ([], primExportSource mn)) - mkTypeEntry _ = internalError - "mkPrimExports.mkTypeEntry: a name is qualified BySourcePos instead of ByModuleName" - mkClassEntry (Qualified (ByModuleName mn) name) = (name, primExportSource mn) - mkClassEntry _ = internalError - "mkPrimExports.mkClassEntry: a name is qualified BySourcePos instead of ByModuleName" +mkTypeEntry (Qualified (ByModuleName mn) name) = (name, ([], primExportSource mn)) +mkTypeEntry _ = internalError + "mkPrimExports.mkTypeEntry: a name is qualified BySourcePos instead of ByModuleName" + +mkClassEntry (Qualified (ByModuleName mn) name) = (name, primExportSource mn) +mkClassEntry _ = internalError + "mkPrimExports.mkClassEntry: a name is qualified BySourcePos instead of ByModuleName" - primExportSource mn = - ExportSource - { exportSourceImportedFrom = Nothing - , exportSourceDefinedIn = mn - } +mkValueEntry (Qualified (ByModuleName mn) name) = (name, primExportSource mn) + +primExportSource mn = + ExportSource + { exportSourceImportedFrom = Nothing + , exportSourceDefinedIn = mn + } -- | Environment which only contains the Prim modules. primEnv :: Env primEnv = M.fromList - [ ( C.M_Prim + [ ( PLC.M_Builtin + , (internalModuleSourceSpan "", nullImports, builtinExports) + ) + , + ( C.M_Prim , (internalModuleSourceSpan "", nullImports, primExports) ) , ( C.M_Prim_Boolean diff --git a/src/Language/PureScript/Sugar/TypeClasses.hs b/src/Language/PureScript/Sugar/TypeClasses.hs index 4f3129baf..ccb699db2 100644 --- a/src/Language/PureScript/Sugar/TypeClasses.hs +++ b/src/Language/PureScript/Sugar/TypeClasses.hs @@ -226,7 +226,7 @@ desugarDecl mn exps = go dictTy = foldl srcTypeApp (srcTypeConstructor (fmap (coerceProperName . dictTypeName) className)) tys constrainedTy = quantify (foldr srcConstrainedType dictTy deps) in - return $ ValueDecl sa name' Private [] [MkUnguarded (TypedValue True dict constrainedTy)] + return $ ValueDecl sa name' Public [] [MkUnguarded (TypedValue True dict constrainedTy)] return (expRef name' className tys, [d, dictDecl]) go other = return (Nothing, [other]) @@ -300,9 +300,10 @@ typeClassMemberToDictionaryAccessor mn name args (TypeDeclaration (TypeDeclarati dictIdent = Ident "dict" dictObjIdent = Ident "v" ctor = ConstructorBinder ss (coerceProperName . dictTypeName <$> className) [VarBinder ss dictObjIdent] - acsr = Accessor (mkString $ runIdent ident) (Var ss (Qualified ByNullSourcePos dictObjIdent)) + -- NOTE: changing this from ByNullSourcePos to the real source pos to hopefully make conversion to typed CoreFn AST work + acsr = Accessor (mkString $ runIdent ident) (Var ss (Qualified {- -ByNullSourcePos -} (BySourcePos $ spanStart ss) dictObjIdent)) visibility = second (const TypeVarVisible) <$> args - in ValueDecl sa ident Private [] + in ValueDecl sa ident Public [] [MkUnguarded ( TypedValue False (Abs (VarBinder ss dictIdent) (Case [Var ss $ Qualified ByNullSourcePos dictIdent] [CaseAlternative [ctor] [MkUnguarded acsr]])) $ addVisibility visibility (moveQuantifiersToFront NullSourceAnn (quantify (srcConstrainedType (srcConstraint className [] (map (srcTypeVar . fst) args) Nothing) ty))) @@ -362,7 +363,7 @@ typeInstanceDictionaryDeclaration sa@(ss, _) name mn deps className tys decls = constrainedTy = quantify (foldr srcConstrainedType dictTy deps) dict = App (Constructor ss (fmap (coerceProperName . dictTypeName) className)) props mkTV = if unreachable then TypedValue False (Var nullSourceSpan C.I_undefined) else TypedValue True dict - result = ValueDecl sa name Private [] [MkUnguarded (mkTV constrainedTy)] + result = ValueDecl sa name Public [] [MkUnguarded (mkTV constrainedTy)] return result where diff --git a/src/Language/PureScript/TypeChecker.hs b/src/Language/PureScript/TypeChecker.hs index 479a01f01..fde27f1ef 100644 --- a/src/Language/PureScript/TypeChecker.hs +++ b/src/Language/PureScript/TypeChecker.hs @@ -5,6 +5,7 @@ module Language.PureScript.TypeChecker ( module T , typeCheckModule , checkNewtype + , typeCheckAll ) where import Prelude diff --git a/src/Language/PureScript/TypeChecker/Entailment.hs b/src/Language/PureScript/TypeChecker/Entailment.hs index 7a3872c1c..7dc100ffe 100644 --- a/src/Language/PureScript/TypeChecker/Entailment.hs +++ b/src/Language/PureScript/TypeChecker/Entailment.hs @@ -33,10 +33,10 @@ import Data.Text qualified as T import Data.List.NonEmpty (NonEmpty(..)) import Data.List.NonEmpty qualified as NEL -import Language.PureScript.AST (Binder(..), ErrorMessageHint(..), Expr(..), Literal(..), pattern NullSourceSpan, everywhereOnValuesTopDownM, nullSourceSpan, everythingOnValues) +import Language.PureScript.AST (Binder(..), ErrorMessageHint(..), Expr(..), Literal(..), pattern NullSourceSpan, everywhereOnValuesTopDownM, nullSourceSpan, everythingOnValues, nullSourceAnn) import Language.PureScript.AST.Declarations (UnknownsHint(..)) import Language.PureScript.Crash (internalError) -import Language.PureScript.Environment (Environment(..), FunctionalDependency(..), TypeClassData(..), dictTypeName, kindRow, tyBoolean, tyInt, tyString) +import Language.PureScript.Environment (Environment(..), FunctionalDependency(..), TypeClassData(..), dictTypeName, kindRow, tyBoolean, tyInt, tyString, mkRecordT) import Language.PureScript.Errors (MultipleErrors, SimpleErrorMessage(..), addHint, addHints, errorMessage, rethrow) import Language.PureScript.Names (pattern ByNullSourcePos, Ident(..), ModuleName, ProperName(..), ProperNameType(..), Qualified(..), QualifiedBy(..), byMaybeModuleName, coerceProperName, disqualify, freshIdent, getQual) import Language.PureScript.TypeChecker.Entailment.Coercible (GivenSolverState(..), WantedSolverState(..), initialGivenSolverState, initialWantedSolverState, insoluble, solveGivens, solveWanteds) @@ -232,6 +232,9 @@ entails SolverOptions{..} constraint context hints = valUndefined :: Expr valUndefined = Var nullSourceSpan C.I_undefined + typedEmptyRecord :: Expr + typedEmptyRecord = TypedValue False (Literal nullSourceSpan $ ObjectLiteral []) (mkRecordT $ REmpty nullSourceAnn) + solve :: SourceConstraint -> WriterT (Any, [(Ident, InstanceContext, SourceConstraint)]) (StateT InstanceContext m) Expr solve = go 0 hints where @@ -466,7 +469,7 @@ entails SolverOptions{..} constraint context hints = -- Turn a DictionaryValue into a Expr subclassDictionaryValue :: Expr -> Qualified (ProperName 'ClassName) -> Integer -> Expr subclassDictionaryValue dict className index = - App (Accessor (mkString (superclassName className index)) dict) valUndefined + App (Accessor (mkString (superclassName className index)) dict) typedEmptyRecord -- valUndefined solveCoercible :: Environment -> InstanceContext -> [SourceType] -> [SourceType] -> m (Maybe [TypeClassDict]) solveCoercible env ctx kinds [a, b] = do diff --git a/src/Language/PureScript/TypeChecker/Monad.hs b/src/Language/PureScript/TypeChecker/Monad.hs index ba27d0299..46be3f3e1 100644 --- a/src/Language/PureScript/TypeChecker/Monad.hs +++ b/src/Language/PureScript/TypeChecker/Monad.hs @@ -72,18 +72,18 @@ emptySubstitution = Substitution M.empty M.empty M.empty -- | State required for type checking data CheckState = CheckState - { checkEnv :: Environment + { checkEnv :: !Environment -- ^ The current @Environment@ - , checkNextType :: Int + , checkNextType :: !Int -- ^ The next type unification variable - , checkNextSkolem :: Int + , checkNextSkolem :: !Int -- ^ The next skolem variable - , checkNextSkolemScope :: Int + , checkNextSkolemScope :: !Int -- ^ The next skolem scope constant - , checkCurrentModule :: Maybe ModuleName + , checkCurrentModule :: !(Maybe ModuleName) -- ^ The current module , checkCurrentModuleImports :: - [ ( SourceAnn + ![ ( SourceAnn , ModuleName , ImportDeclarationType , Maybe ModuleName @@ -94,14 +94,14 @@ data CheckState = CheckState -- Newtype constructors have to be in scope for some Coercible constraints to -- be solvable, so we need to know which constructors are imported and whether -- they are actually defined in or re-exported from the imported modules. - , checkSubstitution :: Substitution + , checkSubstitution :: !Substitution -- ^ The current substitution - , checkHints :: [ErrorMessageHint] + , checkHints :: ![ErrorMessageHint] -- ^ The current error message hint stack. -- This goes into state, rather than using 'rethrow', -- since this way, we can provide good error messages -- during instance resolution. - , checkConstructorImportsForCoercible :: S.Set (ModuleName, Qualified (ProperName 'ConstructorName)) + , checkConstructorImportsForCoercible :: !(S.Set (ModuleName, Qualified (ProperName 'ConstructorName))) -- ^ Newtype constructors imports required to solve Coercible constraints. -- We have to keep track of them so that we don't emit unused import warnings. } @@ -110,6 +110,7 @@ data CheckState = CheckState emptyCheckState :: Environment -> CheckState emptyCheckState env = CheckState env 0 0 0 Nothing [] emptySubstitution [] mempty + -- | Unification variables type Unknown = Int diff --git a/src/Language/PureScript/TypeChecker/Types.hs b/src/Language/PureScript/TypeChecker/Types.hs index 3f758805c..9faf7830d 100644 --- a/src/Language/PureScript/TypeChecker/Types.hs +++ b/src/Language/PureScript/TypeChecker/Types.hs @@ -5,6 +5,19 @@ module Language.PureScript.TypeChecker.Types ( BindingGroupType(..) , typesOf , checkTypeKind + , check + , infer + , inferBinder + , freshTypeWithKind + , kindType + , TypedValue' (..) + , instantiatePolyTypeWithUnknowns + , instantiateForBinders + , tvToExpr + , SplitBindingGroup(..) + , typeDictionaryForBindingGroup + , typeForBindingGroupElement + , checkTypedBindingGroupElement ) where {- @@ -595,12 +608,15 @@ inferLetBinding seen (ValueDecl sa@(ss, _) ident nameKind [] [MkUnguarded (Typed $ inferLetBinding (seen ++ [ValueDecl sa ident nameKind [] [MkUnguarded (TypedValue checkType val' ty'')]]) rest ret j inferLetBinding seen (ValueDecl sa@(ss, _) ident nameKind [] [MkUnguarded val] : rest) ret j = do valTy <- freshTypeWithKind kindType - TypedValue' _ val' valTy' <- warnAndRethrowWithPositionTC ss $ do + TypedValue' chk val' valTy' <- warnAndRethrowWithPositionTC ss $ do let dict = M.singleton (Qualified (BySourcePos $ spanStart ss) ident) (valTy, nameKind, Undefined) bindNames dict $ infer val warnAndRethrowWithPositionTC ss $ unifyTypes valTy valTy' + -- NOTE (from Sean): Returning a TypedValue gives us access to monomorphized types for un-annotated let bindings. + -- I'm not sure why they don't do this, perhaps there is a reason to avoid doing so? + let val'' = TypedValue chk val' valTy' bindNames (M.singleton (Qualified (BySourcePos $ spanStart ss) ident) (valTy', nameKind, Defined)) - $ inferLetBinding (seen ++ [ValueDecl sa ident nameKind [] [MkUnguarded val']]) rest ret j + $ inferLetBinding (seen ++ [ValueDecl sa ident nameKind [] [MkUnguarded val'']]) rest ret j inferLetBinding seen (BindingGroupDeclaration ds : rest) ret j = do moduleName <- unsafeCheckCurrentModule SplitBindingGroup untyped typed dict <- typeDictionaryForBindingGroup Nothing . NEL.toList $ fmap (\(i, _, v) -> (i, v)) ds @@ -713,9 +729,9 @@ instantiateForBinders vals cas = unzip <$> zipWithM (\val inst -> do -- checkBinders :: (MonadSupply m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) - => [SourceType] - -> SourceType - -> [CaseAlternative] + => [SourceType] -- the types of the scrutinee values + -> SourceType -- return type of case expr + -> [CaseAlternative] -- the binders -> m [CaseAlternative] checkBinders _ _ [] = return [] checkBinders nvals ret (CaseAlternative binders result : bs) = do diff --git a/src/Language/PureScript/Types.hs b/src/Language/PureScript/Types.hs index ef00e21a0..12b7198ed 100644 --- a/src/Language/PureScript/Types.hs +++ b/src/Language/PureScript/Types.hs @@ -90,6 +90,7 @@ data Type a -- | Explicit kind application | KindApp a (Type a) (Type a) -- | Forall quantifier + -- \/ TODO: Remove the maybe | ForAll a TypeVarVisibility Text (Maybe (Type a)) (Type a) (Maybe SkolemScope) -- | A type with a set of type class constraints | ConstrainedType a (Constraint a) (Type a) diff --git a/tests/Language/PureScript/Ide/RebuildSpec.hs b/tests/Language/PureScript/Ide/RebuildSpec.hs index 93a0cabe5..7da70065c 100644 --- a/tests/Language/PureScript/Ide/RebuildSpec.hs +++ b/tests/Language/PureScript/Ide/RebuildSpec.hs @@ -15,7 +15,7 @@ import System.Directory (doesFileExist, removePathForcibly) import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy) defaultTarget :: Set P.CodegenTarget -defaultTarget = Set.singleton P.JS +defaultTarget = Set.singleton P.CoreFn load :: [Text] -> Command load = LoadSync . map Test.mn diff --git a/tests/Main.hs b/tests/Main.hs index b8f6ea979..6b8ec2c0e 100644 --- a/tests/Main.hs +++ b/tests/Main.hs @@ -21,6 +21,7 @@ import TestSourceMaps qualified import TestMake qualified import TestUtils qualified import TestGraph qualified +import TestPurus (shouldPassTests) import System.IO (hSetEncoding, stdout, stderr, utf8) @@ -28,21 +29,26 @@ main :: IO () main = do hSetEncoding stdout utf8 hSetEncoding stderr utf8 + shouldPassTests {- do + hSetEncoding stdout utf8 + hSetEncoding stderr utf8 TestUtils.updateSupportCode + shouldPassTests hspec $ do describe "cst" TestCst.spec describe "ast" TestAst.spec - describe "ide" TestIde.spec + -- describe "ide" TestIde.spec beforeAll TestUtils.setupSupportModules $ do describe "compiler" TestCompiler.spec - describe "sourcemaps" TestSourceMaps.spec + -- describe "sourcemaps" TestSourceMaps.spec describe "make" TestMake.spec - describe "psci" TestPsci.spec + -- describe "psci" TestPsci.spec describe "corefn" TestCoreFn.spec - describe "docs" TestDocs.spec - describe "prim-docs" TestPrimDocs.spec - describe "publish" TestPscPublish.spec + -- describe "docs" TestDocs.spec + -- describe "prim-docs" TestPrimDocs.spec + -- describe "publish" TestPscPublish.spec describe "hierarchy" TestHierarchy.spec - describe "graph" TestGraph.spec + -- describe "graph" TestGraph.spec +-} diff --git a/tests/TestCoreFn.hs b/tests/TestCoreFn.hs index 588c6817b..67bcbc9cd 100644 --- a/tests/TestCoreFn.hs +++ b/tests/TestCoreFn.hs @@ -17,14 +17,16 @@ import Language.PureScript.CoreFn.FromJSON (moduleFromJSON) import Language.PureScript.CoreFn.ToJSON (moduleToJSON) import Language.PureScript.Names (pattern ByNullSourcePos, Ident(..), ModuleName(..), ProperName(..), Qualified(..), QualifiedBy(..)) import Language.PureScript.PSString (mkString) +import Language.PureScript.Environment import Test.Hspec (Spec, context, shouldBe, shouldSatisfy, specify) +import Language.PureScript.CoreFn.Desugar.Utils (purusTy) -parseModule :: Value -> Result (Version, Module Ann) +parseModule :: Value -> Result (Version, Module (Bind Ann) Ann) parseModule = parse moduleFromJSON -- convert a module to its json CoreFn representation and back -parseMod :: Module Ann -> Result (Module Ann) +parseMod :: Module (Bind Ann) Ann -> Result (Module (Bind Ann) Ann) parseMod m = let v = Version [0] [] in snd <$> parseModule (moduleToJSON v m) @@ -33,8 +35,10 @@ isSuccess :: Result a -> Bool isSuccess (Success _) = True isSuccess _ = False +-- TODO: Fix spec :: Spec -spec = context "CoreFnFromJson" $ do +spec = pure () {- + context "CoreFnFromJson" $ do let mn = ModuleName "Example.Main" mp = "src/Example/Main.purs" ss = SourceSpan mp (SourcePos 0 0) (SourcePos 0 0) @@ -102,16 +106,17 @@ spec = context "CoreFnFromJson" $ do context "Expr" $ do specify "should parse literals" $ do let m = Module ss [] mn mp [] [] M.empty [] - [ NonRec ann (Ident "x1") $ Literal ann (NumericLiteral (Left 1)) - , NonRec ann (Ident "x2") $ Literal ann (NumericLiteral (Right 1.0)) - , NonRec ann (Ident "x3") $ Literal ann (StringLiteral (mkString "abc")) - , NonRec ann (Ident "x4") $ Literal ann (CharLiteral 'c') - , NonRec ann (Ident "x5") $ Literal ann (BooleanLiteral True) - , NonRec ann (Ident "x6") $ Literal ann (ArrayLiteral [Literal ann (CharLiteral 'a')]) - , NonRec ann (Ident "x7") $ Literal ann (ObjectLiteral [(mkString "a", Literal ann (CharLiteral 'a'))]) + [ NonRec ann (Ident "x1") $ Literal ann (purusTy tyInt) (NumericLiteral (Left 1)) + , NonRec ann (Ident "x2") $ Literal ann (purusTy tyNumber) (NumericLiteral (Right 1.0)) + , NonRec ann (Ident "x3") $ Literal ann (purusTy tyString) (StringLiteral (mkString "abc")) + , NonRec ann (Ident "x4") $ Literal ann (purusTy tyChar) (CharLiteral 'c') + , NonRec ann (Ident "x5") $ Literal ann (purusTy tyBoolean) (BooleanLiteral True) + , NonRec ann (Ident "x6") $ Literal ann (arrayT tyChar) (ArrayLiteral [Literal ann (purusTy tyChar) (CharLiteral 'a')]) + -- TODO: Need helpers to make the type + -- , NonRec ann (Ident "x7") $ Literal ann (ObjectLiteral [(mkString "a", Literal ann (CharLiteral 'a'))]) ] parseMod m `shouldSatisfy` isSuccess - +{- don't have the tools to write type sigs, TODO come back an fix specify "should parse Constructor" $ do let m = Module ss [] mn mp [] [] M.empty [] [ NonRec ann (Ident "constructor") $ Constructor ann (ProperName "Either") (ProperName "Left") [Ident "value0"] ] @@ -256,7 +261,7 @@ spec = context "CoreFnFromJson" $ do ] ] parseMod m `shouldSatisfy` isSuccess - + -} context "Comments" $ do specify "should parse LineComment" $ do let m = Module ss [ LineComment "line" ] mn mp [] [] M.empty [] [] @@ -265,3 +270,4 @@ spec = context "CoreFnFromJson" $ do specify "should parse BlockComment" $ do let m = Module ss [ BlockComment "block" ] mn mp [] [] M.empty [] [] parseMod m `shouldSatisfy` isSuccess +-} diff --git a/tests/TestMake.hs b/tests/TestMake.hs index 610e8465c..6cd5347f4 100644 --- a/tests/TestMake.hs +++ b/tests/TestMake.hs @@ -164,7 +164,7 @@ spec = do let modulePath = sourcesDir "Module.purs" moduleContent1 = "module Module where\nx :: Int\nx = 1" moduleContent2 = moduleContent1 <> "\ny :: Int\ny = 1" - optsWithDocs = P.defaultOptions { P.optionsCodegenTargets = Set.fromList [P.JS, P.Docs] } + optsWithDocs = P.defaultOptions { P.optionsCodegenTargets = Set.fromList [P.CoreFn, P.Docs] } go opts = compileWithOptions opts [modulePath] >>= assertSuccess oneSecond = 10 ^ (6::Int) -- microseconds. diff --git a/tests/TestPurus.hs b/tests/TestPurus.hs new file mode 100644 index 000000000..e3e8a7206 --- /dev/null +++ b/tests/TestPurus.hs @@ -0,0 +1,143 @@ +{-# LANGUAGE TypeApplications #-} +module TestPurus where + +import Prelude +import Command.Compile ( compileForTests, PSCMakeOptions(..) ) +import Control.Monad (when,unless,void) +import System.FilePath +import Language.PureScript qualified as P +import Data.Set qualified as S +import Data.Foldable (traverse_) +import System.Directory (removeDirectoryRecursive, doesDirectoryExist, createDirectory) +import System.FilePath.Glob qualified as Glob +import Data.Function (on) +import Data.List (sort, sortBy, stripPrefix, groupBy, find) +import Control.Exception.Base +import Language.PureScript.CoreFn.Convert.ToPIR +import PlutusCore.Core +import Test.Tasty +import PlutusCore.Evaluation.Machine.Ck (EvaluationResult(..)) +import PlutusCore +import PlutusCore.Default + +shouldPassTests :: IO () +shouldPassTests = do + traverse_ runPurusDefault shouldPass + -- let misc = "./tests/purus/passing/Misc/output/Lib/index.cfn" + {- UPLC tests disabled atm while we rewrite stuff + + uplc1 <- declToUPLC misc "main" + writeFile "./tests/purus/passing/Misc/output/Lib/main.plc" (show uplc1) + uplc2 <- declToUPLC misc "minus" + writeFile "./tests/purus/passing/Misc/output/Lib/fakeminus.plc" (show uplc2) + defaultMain $ + runPLCProgramTest + "mainTest" + (EvaluationSuccess (Constant () (Some (ValueOf DefaultUniInteger 2))),[]) + misc + "main" + -} +runPurus :: P.CodegenTarget -> FilePath -> IO () +runPurus target dir = do + outDirExists <- doesDirectoryExist outputDir + when (target /= P.CheckCoreFn) $ do + when outDirExists $ removeDirectoryRecursive outputDir + unless outDirExists $ createDirectory outputDir + files <- concat <$> getTestFiles dir + print files + print ("Compiling " <> dir) + compileForTests (makeOpts files) + print ("Done with " <> dir) + where + outputDir = "tests" "purus" dir "output" + + makeOpts :: [FilePath] -> PSCMakeOptions + makeOpts files = PSCMakeOptions { + pscmInput = files, + pscmExclude = [], + pscmOutputDir = outputDir, + pscmOpts = purusOpts, + pscmUsePrefix = False, + pscmJSONErrors = False + } + + purusOpts :: P.Options + purusOpts = P.Options { + optionsVerboseErrors = True, + optionsNoComments = True, + optionsCodegenTargets = S.singleton target + } + +runPurusDefault :: FilePath -> IO () +runPurusDefault path = runPurus P.CoreFn path + +runPurusGolden :: FilePath -> IO () +runPurusGolden path = runPurus P.CheckCoreFn path + + +shouldPass :: [FilePath] +shouldPass = map (prefix ) paths + where + prefix = "passing" + paths = [ + "2018", + "2138", + "2609", + "4035", + "4101", + "4105", + "4200", + "4310", + "ClassRefSyntax", + "Coercible", + "DctorOperatorAlias", + "ExplicitImportReExport", + "ExportExplicit", + "ExportExplicit2", + "ForeignKind", + "Import", + "ImportExplicit", + "ImportQualified", + "InstanceUnnamedSimilarClassName", + "ModuleDeps", + "Misc", + "NonOrphanInstanceFunDepExtra", + "NonOrphanInstanceMulti", + "PendingConflictingImports", + "PendingConflictingImports2", + "RedefinedFixity", + "ReExportQualified", + "ResolvableScopeConflict", + "ResolvableScopeConflict2", + "ResolvableScopeConflict3", + "ShadowedModuleName", + "TransitiveImport" + ] + + +getTestFiles :: FilePath -> IO [[FilePath]] +getTestFiles testDir = do + let dir = "tests" "purus" testDir + getFiles dir <$> testGlob dir + where + -- A glob for all purs and js files within a test directory + testGlob :: FilePath -> IO [FilePath] + testGlob = Glob.globDir1 (Glob.compile "**/*.purs") + -- Groups the test files so that a top-level file can have dependencies in a + -- subdirectory of the same name. The inner tuple contains a list of the + -- .purs files and the .js files for the test case. + getFiles :: FilePath -> [FilePath] -> [[FilePath]] + getFiles baseDir + = map (filter ((== ".purs") . takeExtensions) . map (baseDir )) + . groupBy ((==) `on` extractPrefix) + . sortBy (compare `on` extractPrefix) + . map (makeRelative baseDir) + -- Extracts the filename part of a .purs file, or if the file is in a + -- subdirectory, the first part of that directory path. + extractPrefix :: FilePath -> FilePath + extractPrefix fp = + let dir = takeDirectory fp + ext = reverse ".purs" + in if dir == "." + then maybe fp reverse $ stripPrefix ext $ reverse fp + else dir diff --git a/tests/TestSourceMaps.hs b/tests/TestSourceMaps.hs index 5b91017d5..ae931b886 100644 --- a/tests/TestSourceMaps.hs +++ b/tests/TestSourceMaps.hs @@ -67,7 +67,7 @@ assertCompilesToExpectedValidOutput support inputFiles = do where compilationOptions :: P.Options - compilationOptions = P.defaultOptions { P.optionsCodegenTargets = Set.fromList [P.JS, P.JSSourceMap] } + compilationOptions = P.defaultOptions { P.optionsCodegenTargets = Set.fromList [P.CoreFn] } -- | Fails the test if the produced source maps are not valid. sourceMapIsValid :: FilePath -> Expectation diff --git a/tests/purs/docs/output/ChildDeclOrder/docs.json b/tests/purs/docs/output/ChildDeclOrder/docs.json new file mode 100644 index 000000000..480bc67b0 --- /dev/null +++ b/tests/purs/docs/output/ChildDeclOrder/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[8,10],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[8,3]},"title":"First"},{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[9,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[9,3]},"title":"Second"},{"comments":null,"info":{"declType":"instance","dependencies":[],"type":{"annotation":[],"contents":[{"annotation":[],"contents":[["ChildDeclOrder"],"Show"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["ChildDeclOrder"],"Two"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[19,15],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[18,1]},"title":"showTwo"},{"comments":null,"info":{"declType":"instance","dependencies":[],"type":{"annotation":[],"contents":[{"annotation":[],"contents":[["ChildDeclOrder"],"Foo"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["ChildDeclOrder"],"Two"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[23,16],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[21,1]},"title":"fooTwo"}],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[9,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[7,1]},"title":"Two"},{"children":[{"comments":null,"info":{"declType":"typeClassMember","type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[12,22],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[12,3]},"title":"show"},{"comments":null,"info":{"declType":"instance","dependencies":[],"type":{"annotation":[],"contents":[{"annotation":[],"contents":[["ChildDeclOrder"],"Show"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["ChildDeclOrder"],"Two"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[19,15],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[18,1]},"title":"showTwo"}],"comments":null,"info":{"arguments":[["a",null]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[12,22],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[11,1]},"title":"Show"},{"children":[{"comments":null,"info":{"declType":"typeClassMember","type":{"annotation":[],"contents":"a","tag":"TypeVar"}},"sourceSpan":{"end":[15,12],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[15,3]},"title":"foo1"},{"comments":null,"info":{"declType":"typeClassMember","type":{"annotation":[],"contents":"a","tag":"TypeVar"}},"sourceSpan":{"end":[16,12],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[16,3]},"title":"foo2"},{"comments":null,"info":{"declType":"instance","dependencies":[],"type":{"annotation":[],"contents":[{"annotation":[],"contents":[["ChildDeclOrder"],"Foo"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["ChildDeclOrder"],"Two"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[23,16],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[21,1]},"title":"fooTwo"},{"comments":null,"info":{"declType":"instance","dependencies":[],"type":{"annotation":[],"contents":[{"annotation":[],"contents":[["ChildDeclOrder"],"Foo"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[27,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[25,1]},"title":"fooInt"}],"comments":null,"info":{"arguments":[["a",null]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[16,12],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ChildDeclOrder.purs","start":[14,1]},"title":"Foo"}],"name":"ChildDeclOrder","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/ChildDeclOrder/externs.cbor b/tests/purs/docs/output/ChildDeclOrder/externs.cbor new file mode 100644 index 000000000..78989a901 Binary files /dev/null and b/tests/purs/docs/output/ChildDeclOrder/externs.cbor differ diff --git a/tests/purs/docs/output/Clash/docs.json b/tests/purs/docs/output/Clash/docs.json new file mode 100644 index 000000000..ac362d7c5 --- /dev/null +++ b/tests/purs/docs/output/Clash/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"Clash","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Clash/externs.cbor b/tests/purs/docs/output/Clash/externs.cbor new file mode 100644 index 000000000..0c1777bb7 Binary files /dev/null and b/tests/purs/docs/output/Clash/externs.cbor differ diff --git a/tests/purs/docs/output/Clash1/docs.json b/tests/purs/docs/output/Clash1/docs.json new file mode 100644 index 000000000..649a175bd --- /dev/null +++ b/tests/purs/docs/output/Clash1/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"Clash1","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Clash1/externs.cbor b/tests/purs/docs/output/Clash1/externs.cbor new file mode 100644 index 000000000..5d2fc758d Binary files /dev/null and b/tests/purs/docs/output/Clash1/externs.cbor differ diff --git a/tests/purs/docs/output/Clash1a/docs.json b/tests/purs/docs/output/Clash1a/docs.json new file mode 100644 index 000000000..f03805552 --- /dev/null +++ b/tests/purs/docs/output/Clash1a/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[3,13],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/Clash1a.purs","start":[3,1]},"title":"value"},{"children":[],"comments":null,"info":{"arguments":[],"declType":"typeSynonym","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[6,17],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/Clash1a.purs","start":[6,1]},"title":"Type'"},{"children":[{"comments":null,"info":{"declType":"typeClassMember","type":{"annotation":[],"contents":"a","tag":"TypeVar"}},"sourceSpan":{"end":[9,23],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/Clash1a.purs","start":[9,3]},"title":"typeClassMember"}],"comments":null,"info":{"arguments":[["a",null]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[9,23],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/Clash1a.purs","start":[8,1]},"title":"TypeClass"}],"name":"Clash1a","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Clash1a/externs.cbor b/tests/purs/docs/output/Clash1a/externs.cbor new file mode 100644 index 000000000..e5be38fe9 Binary files /dev/null and b/tests/purs/docs/output/Clash1a/externs.cbor differ diff --git a/tests/purs/docs/output/Clash2/docs.json b/tests/purs/docs/output/Clash2/docs.json new file mode 100644 index 000000000..671c27201 --- /dev/null +++ b/tests/purs/docs/output/Clash2/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"Clash2","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Clash2/externs.cbor b/tests/purs/docs/output/Clash2/externs.cbor new file mode 100644 index 000000000..0b407088b Binary files /dev/null and b/tests/purs/docs/output/Clash2/externs.cbor differ diff --git a/tests/purs/docs/output/Clash2a/docs.json b/tests/purs/docs/output/Clash2a/docs.json new file mode 100644 index 000000000..26b2b19bf --- /dev/null +++ b/tests/purs/docs/output/Clash2a/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[3,16],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/Clash2a.purs","start":[3,1]},"title":"value"},{"children":[],"comments":null,"info":{"arguments":[],"declType":"typeSynonym","type":{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[6,20],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/Clash2a.purs","start":[6,1]},"title":"Type'"},{"children":[{"comments":null,"info":{"declType":"typeClassMember","type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}},"sourceSpan":{"end":[9,28],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/Clash2a.purs","start":[9,3]},"title":"typeClassMember"}],"comments":null,"info":{"arguments":[["a",null],["b",null]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[9,28],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/Clash2a.purs","start":[8,1]},"title":"TypeClass"}],"name":"Clash2a","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Clash2a/externs.cbor b/tests/purs/docs/output/Clash2a/externs.cbor new file mode 100644 index 000000000..b6dbda314 Binary files /dev/null and b/tests/purs/docs/output/Clash2a/externs.cbor differ diff --git a/tests/purs/docs/output/ConstrainedArgument/docs.json b/tests/purs/docs/output/ConstrainedArgument/docs.json new file mode 100644 index 000000000..657aa8438 --- /dev/null +++ b/tests/purs/docs/output/ConstrainedArgument/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"arguments":[["t",{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[3,22],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ConstrainedArgument.purs","start":[3,1]},"title":"Foo"},{"children":[],"comments":null,"info":{"arguments":[],"declType":"typeSynonym","type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"constraintAnn":[],"constraintArgs":[],"constraintClass":[["Prim"],"Partial"],"constraintData":null,"constraintKindArgs":[]},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"ConstrainedType"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[5,54],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ConstrainedArgument.purs","start":[5,1]},"title":"WithoutArgs"},{"children":[],"comments":null,"info":{"arguments":[],"declType":"typeSynonym","type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"constraintAnn":[],"constraintArgs":[{"annotation":[],"contents":"a","tag":"TypeVar"}],"constraintClass":[["ConstrainedArgument"],"Foo"],"constraintData":null,"constraintKindArgs":[]},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"ConstrainedType"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[6,52],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ConstrainedArgument.purs","start":[6,1]},"title":"WithArgs"},{"children":[],"comments":null,"info":{"arguments":[],"declType":"typeSynonym","type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"constraintAnn":[],"constraintArgs":[],"constraintClass":[["Prim"],"Partial"],"constraintData":null,"constraintKindArgs":[]},{"annotation":[],"contents":[{"constraintAnn":[],"constraintArgs":[],"constraintClass":[["Prim"],"Partial"],"constraintData":null,"constraintKindArgs":[]},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"ConstrainedType"}],"tag":"ConstrainedType"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[7,65],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ConstrainedArgument.purs","start":[7,1]},"title":"MultiWithoutArgs"},{"children":[],"comments":null,"info":{"arguments":[],"declType":"typeSynonym","type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"b","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"constraintAnn":[],"constraintArgs":[{"annotation":[],"contents":"a","tag":"TypeVar"}],"constraintClass":[["ConstrainedArgument"],"Foo"],"constraintData":null,"constraintKindArgs":[]},{"annotation":[],"contents":[{"constraintAnn":[],"constraintArgs":[{"annotation":[],"contents":"b","tag":"TypeVar"}],"constraintClass":[["ConstrainedArgument"],"Foo"],"constraintData":null,"constraintKindArgs":[]},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"ConstrainedType"}],"tag":"ConstrainedType"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[8,63],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ConstrainedArgument.purs","start":[8,1]},"title":"MultiWithArgs"}],"name":"ConstrainedArgument","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/ConstrainedArgument/externs.cbor b/tests/purs/docs/output/ConstrainedArgument/externs.cbor new file mode 100644 index 000000000..167560479 Binary files /dev/null and b/tests/purs/docs/output/ConstrainedArgument/externs.cbor differ diff --git a/tests/purs/docs/output/Data.Newtype/docs.json b/tests/purs/docs/output/Data.Newtype/docs.json new file mode 100644 index 000000000..1e88e304d --- /dev/null +++ b/tests/purs/docs/output/Data.Newtype/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"arguments":[["t",null],["a",null]],"declType":"typeClass","fundeps":[[["t"],["a"]]],"superclasses":[{"constraintAnn":[],"constraintArgs":[{"annotation":[],"contents":"t","tag":"TypeVar"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"constraintClass":[["Prim","Coerce"],"Coercible"],"constraintData":null,"constraintKindArgs":[]}]},"kind":null,"sourceSpan":{"end":[6,44],"name":"bower_components/purescript-newtype/src/Data/Newtype.purs","start":[6,1]},"title":"Newtype"}],"name":"Data.Newtype","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Data.Newtype/externs.cbor b/tests/purs/docs/output/Data.Newtype/externs.cbor new file mode 100644 index 000000000..d097afa15 Binary files /dev/null and b/tests/purs/docs/output/Data.Newtype/externs.cbor differ diff --git a/tests/purs/docs/output/DeclOrder/docs.json b/tests/purs/docs/output/DeclOrder/docs.json new file mode 100644 index 000000000..437aad1c7 --- /dev/null +++ b/tests/purs/docs/output/DeclOrder/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"arguments":[],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[16,8],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrder.purs","start":[16,1]},"title":"A"},{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[10,7],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrder.purs","start":[10,1]},"title":"x1"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[13,8],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrder.purs","start":[13,1]},"title":"X2"},{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[11,7],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrder.purs","start":[11,1]},"title":"x3"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[14,8],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrder.purs","start":[14,1]},"title":"X4"},{"children":[],"comments":null,"info":{"arguments":[],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[17,8],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrder.purs","start":[17,1]},"title":"B"}],"name":"DeclOrder","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/DeclOrder/externs.cbor b/tests/purs/docs/output/DeclOrder/externs.cbor new file mode 100644 index 000000000..302b96cca Binary files /dev/null and b/tests/purs/docs/output/DeclOrder/externs.cbor differ diff --git a/tests/purs/docs/output/DeclOrderNoExportList/docs.json b/tests/purs/docs/output/DeclOrderNoExportList/docs.json new file mode 100644 index 000000000..4585db7cd --- /dev/null +++ b/tests/purs/docs/output/DeclOrderNoExportList/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[3,7],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrderNoExportList.purs","start":[3,1]},"title":"x1"},{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[4,7],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrderNoExportList.purs","start":[4,1]},"title":"x3"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[6,8],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrderNoExportList.purs","start":[6,1]},"title":"X2"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[7,8],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrderNoExportList.purs","start":[7,1]},"title":"X4"},{"children":[],"comments":null,"info":{"arguments":[],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[9,8],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrderNoExportList.purs","start":[9,1]},"title":"A"},{"children":[],"comments":null,"info":{"arguments":[],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[10,8],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DeclOrderNoExportList.purs","start":[10,1]},"title":"B"}],"name":"DeclOrderNoExportList","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/DeclOrderNoExportList/externs.cbor b/tests/purs/docs/output/DeclOrderNoExportList/externs.cbor new file mode 100644 index 000000000..95a721b4c Binary files /dev/null and b/tests/purs/docs/output/DeclOrderNoExportList/externs.cbor differ diff --git a/tests/purs/docs/output/DocComments/docs.json b/tests/purs/docs/output/DocComments/docs.json new file mode 100644 index 000000000..8b91fa549 --- /dev/null +++ b/tests/purs/docs/output/DocComments/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":"This declaration has a code block:\n\n example == 0\n\nHere we are really testing that the leading whitespace is not stripped, as\nthis ensures that we don't accidentally change code blocks into normal\nparagraphs.\n","info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[10,15],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocComments.purs","start":[10,1]},"title":"example"}],"name":"DocComments","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/DocComments/externs.cbor b/tests/purs/docs/output/DocComments/externs.cbor new file mode 100644 index 000000000..0b5155fb8 Binary files /dev/null and b/tests/purs/docs/output/DocComments/externs.cbor differ diff --git a/tests/purs/docs/output/DocCommentsClassMethod/docs.json b/tests/purs/docs/output/DocCommentsClassMethod/docs.json new file mode 100644 index 000000000..0a4032caa --- /dev/null +++ b/tests/purs/docs/output/DocCommentsClassMethod/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[{"comments":"class method comment\n","info":{"declType":"typeClassMember","type":{"annotation":[],"contents":"a","tag":"TypeVar"}},"sourceSpan":{"end":[5,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsClassMethod.purs","start":[5,3]},"title":"bar"},{"comments":null,"info":{"declType":"typeClassMember","type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}},"sourceSpan":{"end":[6,21],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsClassMethod.purs","start":[6,3]},"title":"baz"}],"comments":null,"info":{"arguments":[["a",null]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[6,21],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsClassMethod.purs","start":[3,1]},"title":"Foo"}],"name":"DocCommentsClassMethod","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/DocCommentsClassMethod/externs.cbor b/tests/purs/docs/output/DocCommentsClassMethod/externs.cbor new file mode 100644 index 000000000..48a89d460 Binary files /dev/null and b/tests/purs/docs/output/DocCommentsClassMethod/externs.cbor differ diff --git a/tests/purs/docs/output/DocCommentsDataConstructor/docs.json b/tests/purs/docs/output/DocCommentsDataConstructor/docs.json new file mode 100644 index 000000000..cd0421dff --- /dev/null +++ b/tests/purs/docs/output/DocCommentsDataConstructor/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[{"comments":"data constructor comment\n","info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[5,8],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsDataConstructor.purs","start":[5,3]},"title":"Bar"},{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[6,8],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsDataConstructor.purs","start":[6,3]},"title":"Baz"}],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[6,8],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsDataConstructor.purs","start":[3,1]},"title":"Foo"},{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":"a","tag":"TypeVar"}],"declType":"dataConstructor"},"sourceSpan":{"end":[9,15],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsDataConstructor.purs","start":[9,3]},"title":"ComplexBar"},{"comments":"another data constructor comment\n","info":{"arguments":[{"annotation":[],"contents":"a","tag":"TypeVar"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"declType":"dataConstructor"},"sourceSpan":{"end":[11,15],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsDataConstructor.purs","start":[11,3]},"title":"ComplexBaz"}],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Representational","Representational"],"typeArguments":[["a",null],["b",null]]},"kind":null,"sourceSpan":{"end":[11,19],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsDataConstructor.purs","start":[8,1]},"title":"ComplexFoo"},{"children":[{"comments":"newtype data constructor comment\n","info":{"arguments":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[],"contents":["newtypeBar",{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},{"annotation":[],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"declType":"dataConstructor"},"sourceSpan":{"end":[15,40],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsDataConstructor.purs","start":[15,3]},"title":"NewtypeFoo"}],"comments":null,"info":{"dataDeclType":"newtype","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[15,40],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsDataConstructor.purs","start":[13,1]},"title":"NewtypeFoo"}],"name":"DocCommentsDataConstructor","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/DocCommentsDataConstructor/externs.cbor b/tests/purs/docs/output/DocCommentsDataConstructor/externs.cbor new file mode 100644 index 000000000..147159eef Binary files /dev/null and b/tests/purs/docs/output/DocCommentsDataConstructor/externs.cbor differ diff --git a/tests/purs/docs/output/DocCommentsMerge/docs.json b/tests/purs/docs/output/DocCommentsMerge/docs.json new file mode 100644 index 000000000..50a2c34cb --- /dev/null +++ b/tests/purs/docs/output/DocCommentsMerge/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[4,25],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[4,15]},"title":"DataOnly"}],"comments":"decl\n","info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[4,25],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[4,1]},"title":"DataOnly"},{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[8,33],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[8,19]},"title":"KindOnlyData"}],"comments":"kind\n","info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[8,33],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[8,1]},"title":"KindOnlyData"},{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[13,31],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[13,18]},"title":"KindAndData"}],"comments":"kind\n\ndecl\n","info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[13,31],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[13,1]},"title":"KindAndData"},{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":"a","tag":"TypeVar"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"declType":"dataConstructor"},"sourceSpan":{"end":[15,37],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[15,23]},"title":"DataRoleOnly"}],"comments":"role\n","info":{"dataDeclType":"data","declType":"data","roles":["Representational","Representational"],"typeArguments":[["a",null],["b",null]]},"kind":null,"sourceSpan":{"end":[15,41],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[15,1]},"title":"DataRoleOnly"},{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":"a","tag":"TypeVar"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"declType":"dataConstructor"},"sourceSpan":{"end":[20,35],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[20,22]},"title":"DataAndRole"}],"comments":"decl\n\nrole\n","info":{"dataDeclType":"data","declType":"data","roles":["Representational","Representational"],"typeArguments":[["a",null],["b",null]]},"kind":null,"sourceSpan":{"end":[20,39],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[20,1]},"title":"DataAndRole"},{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[26,51],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[26,29]},"title":"KindOnlyDataRoleOnly"}],"comments":"kind\n\nrole\n","info":{"dataDeclType":"data","declType":"data","roles":["Representational"],"typeArguments":[["a",null]]},"kind":null,"sourceSpan":{"end":[26,51],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[26,1]},"title":"KindOnlyDataRoleOnly"},{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[33,41],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[33,24]},"title":"KindDataAndRole"}],"comments":"kind\n\ndecl\n\nrole\n","info":{"dataDeclType":"data","declType":"data","roles":["Representational"],"typeArguments":[["a",null]]},"kind":null,"sourceSpan":{"end":[33,41],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[33,1]},"title":"KindDataAndRole"},{"children":[],"comments":"decl\n","info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[40,36],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[40,1]},"title":"FFIOnly"},{"children":[],"comments":"role\n","info":{"dataDeclType":"data","declType":"data","roles":["Representational"],"typeArguments":[["t0",null]]},"kind":null,"sourceSpan":{"end":[42,48],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[42,1]},"title":"FFIRoleOnly"},{"children":[],"comments":"decl\n\nrole\n","info":{"dataDeclType":"data","declType":"data","roles":["Representational"],"typeArguments":[["t0",null]]},"kind":null,"sourceSpan":{"end":[47,47],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[47,1]},"title":"FFIAndRole"},{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"declType":"dataConstructor"},"sourceSpan":{"end":[54,38],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[54,21]},"title":"NewtypeOnly"}],"comments":"decl\n","info":{"dataDeclType":"newtype","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[54,38],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[54,1]},"title":"NewtypeOnly"},{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"declType":"dataConstructor"},"sourceSpan":{"end":[58,46],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[58,25]},"title":"KindOnlyNewtype"}],"comments":"kind\n","info":{"dataDeclType":"newtype","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[58,46],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[58,1]},"title":"KindOnlyNewtype"},{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"declType":"dataConstructor"},"sourceSpan":{"end":[63,48],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[63,28]},"title":"KindAndNewtype"}],"comments":"kind\n\ndecl\n","info":{"dataDeclType":"newtype","declType":"data","roles":["Phantom","Phantom"],"typeArguments":[["a",null],["b",null]]},"kind":null,"sourceSpan":{"end":[63,48],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[63,1]},"title":"KindAndNewtype"},{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"declType":"dataConstructor"},"sourceSpan":{"end":[65,50],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[65,29]},"title":"NewtypeRoleOnly"}],"comments":"role\n","info":{"dataDeclType":"newtype","declType":"data","roles":["Representational","Representational"],"typeArguments":[["a",null],["b",null]]},"kind":{"keyword":"newtype","kind":{"annotation":[],"contents":{"identifier":"k1","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"k2","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k1","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k2","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"sourceSpan":{"end":[65,50],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[65,1]},"title":"NewtypeRoleOnly"},{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"declType":"dataConstructor"},"sourceSpan":{"end":[70,48],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[70,28]},"title":"NewtypeAndRole"}],"comments":"decl\n\nrole\n","info":{"dataDeclType":"newtype","declType":"data","roles":["Representational","Representational"],"typeArguments":[["a",null],["b",null]]},"kind":{"keyword":"newtype","kind":{"annotation":[],"contents":{"identifier":"k1","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"k2","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k1","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k2","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"sourceSpan":{"end":[70,48],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[70,1]},"title":"NewtypeAndRole"},{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"declType":"dataConstructor"},"sourceSpan":{"end":[76,66],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[76,37]},"title":"KindOnlyNewtypeRoleOnly"}],"comments":"kind\n\nrole\n","info":{"dataDeclType":"newtype","declType":"data","roles":["Representational","Representational"],"typeArguments":[["a",null],["b",null]]},"kind":null,"sourceSpan":{"end":[76,66],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[76,1]},"title":"KindOnlyNewtypeRoleOnly"},{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"declType":"dataConstructor"},"sourceSpan":{"end":[83,56],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[83,32]},"title":"KindNewtypeAndRole"}],"comments":"kind\n\ndecl\n\nrole\n","info":{"dataDeclType":"newtype","declType":"data","roles":["Representational","Representational"],"typeArguments":[["a",null],["b",null]]},"kind":null,"sourceSpan":{"end":[83,56],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[83,1]},"title":"KindNewtypeAndRole"},{"children":[],"comments":"decl\n","info":{"arguments":[],"declType":"typeSynonym","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[90,20],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[90,1]},"title":"TypeOnly"},{"children":[],"comments":"kind\n","info":{"arguments":[["a",null],["b",null]],"declType":"typeSynonym","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[94,28],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[94,1]},"title":"KindOnlyType"},{"children":[],"comments":"kind\n\ndecl\n","info":{"arguments":[["a",null],["b",null]],"declType":"typeSynonym","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[99,27],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[99,1]},"title":"KindAndType"},{"children":[],"comments":"decl\n","info":{"arguments":[],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[106,16],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[106,1]},"title":"ClassOnly"},{"children":[],"comments":"kind\n","info":{"arguments":[],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[110,20],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[110,1]},"title":"KindOnlyClass"},{"children":[{"comments":null,"info":{"declType":"typeClassMember","type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[116,33],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[116,3]},"title":"fooKindAndClass"}],"comments":"kind\n\ndecl\n","info":{"arguments":[["a",null]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[116,33],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DocCommentsMerge.purs","start":[115,1]},"title":"KindAndClass"}],"name":"DocCommentsMerge","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/DocCommentsMerge/externs.cbor b/tests/purs/docs/output/DocCommentsMerge/externs.cbor new file mode 100644 index 000000000..051a46476 Binary files /dev/null and b/tests/purs/docs/output/DocCommentsMerge/externs.cbor differ diff --git a/tests/purs/docs/output/DuplicateNames/docs.json b/tests/purs/docs/output/DuplicateNames/docs.json new file mode 100644 index 000000000..a5818bdce --- /dev/null +++ b/tests/purs/docs/output/DuplicateNames/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[8,12],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/DuplicateNames.purs","start":[8,1]},"title":"unit"}],"name":"DuplicateNames","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/DuplicateNames/externs.cbor b/tests/purs/docs/output/DuplicateNames/externs.cbor new file mode 100644 index 000000000..fed16aeaf Binary files /dev/null and b/tests/purs/docs/output/DuplicateNames/externs.cbor differ diff --git a/tests/purs/docs/output/Example/docs.json b/tests/purs/docs/output/Example/docs.json new file mode 100644 index 000000000..3b7928d1e --- /dev/null +++ b/tests/purs/docs/output/Example/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"Example","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Example/externs.cbor b/tests/purs/docs/output/Example/externs.cbor new file mode 100644 index 000000000..82cb73033 Binary files /dev/null and b/tests/purs/docs/output/Example/externs.cbor differ diff --git a/tests/purs/docs/output/Example2/docs.json b/tests/purs/docs/output/Example2/docs.json new file mode 100644 index 000000000..e86440c92 --- /dev/null +++ b/tests/purs/docs/output/Example2/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[3,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/Example2.purs","start":[3,1]},"title":"one"},{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[6,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/Example2.purs","start":[6,1]},"title":"two"}],"name":"Example2","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Example2/externs.cbor b/tests/purs/docs/output/Example2/externs.cbor new file mode 100644 index 000000000..cec286027 Binary files /dev/null and b/tests/purs/docs/output/Example2/externs.cbor differ diff --git a/tests/purs/docs/output/ExplicitExport/docs.json b/tests/purs/docs/output/ExplicitExport/docs.json new file mode 100644 index 000000000..2b4de0a0f --- /dev/null +++ b/tests/purs/docs/output/ExplicitExport/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[3,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ExplicitExport.purs","start":[3,1]},"title":"one"}],"name":"ExplicitExport","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/ExplicitExport/externs.cbor b/tests/purs/docs/output/ExplicitExport/externs.cbor new file mode 100644 index 000000000..fdbe3f32b Binary files /dev/null and b/tests/purs/docs/output/ExplicitExport/externs.cbor differ diff --git a/tests/purs/docs/output/ExplicitTypeSignatures/docs.json b/tests/purs/docs/output/ExplicitTypeSignatures/docs.json new file mode 100644 index 000000000..af44ace5c --- /dev/null +++ b/tests/purs/docs/output/ExplicitTypeSignatures/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":{"identifier":"something","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"something","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":"something","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[6,53],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ExplicitTypeSignatures.purs","start":[6,1]},"title":"explicit"},{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[12,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ExplicitTypeSignatures.purs","start":[12,1]},"title":"anInt"},{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Number"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[16,14],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ExplicitTypeSignatures.purs","start":[16,1]},"title":"aNumber"}],"name":"ExplicitTypeSignatures","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/ExplicitTypeSignatures/externs.cbor b/tests/purs/docs/output/ExplicitTypeSignatures/externs.cbor new file mode 100644 index 000000000..befe86b04 Binary files /dev/null and b/tests/purs/docs/output/ExplicitTypeSignatures/externs.cbor differ diff --git a/tests/purs/docs/output/ImportedTwice/docs.json b/tests/purs/docs/output/ImportedTwice/docs.json new file mode 100644 index 000000000..f3b641419 --- /dev/null +++ b/tests/purs/docs/output/ImportedTwice/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"ImportedTwice","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/ImportedTwice/externs.cbor b/tests/purs/docs/output/ImportedTwice/externs.cbor new file mode 100644 index 000000000..3adb703a4 Binary files /dev/null and b/tests/purs/docs/output/ImportedTwice/externs.cbor differ diff --git a/tests/purs/docs/output/ImportedTwiceA/docs.json b/tests/purs/docs/output/ImportedTwiceA/docs.json new file mode 100644 index 000000000..8670212ba --- /dev/null +++ b/tests/purs/docs/output/ImportedTwiceA/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"ImportedTwiceA","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/ImportedTwiceA/externs.cbor b/tests/purs/docs/output/ImportedTwiceA/externs.cbor new file mode 100644 index 000000000..023d75f16 Binary files /dev/null and b/tests/purs/docs/output/ImportedTwiceA/externs.cbor differ diff --git a/tests/purs/docs/output/ImportedTwiceB/docs.json b/tests/purs/docs/output/ImportedTwiceB/docs.json new file mode 100644 index 000000000..307c9ca1d --- /dev/null +++ b/tests/purs/docs/output/ImportedTwiceB/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[3,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/ImportedTwiceB.purs","start":[3,1]},"title":"foo"}],"name":"ImportedTwiceB","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/ImportedTwiceB/externs.cbor b/tests/purs/docs/output/ImportedTwiceB/externs.cbor new file mode 100644 index 000000000..0b1e2ecf7 Binary files /dev/null and b/tests/purs/docs/output/ImportedTwiceB/externs.cbor differ diff --git a/tests/purs/docs/output/MultiVirtual/docs.json b/tests/purs/docs/output/MultiVirtual/docs.json new file mode 100644 index 000000000..423056c12 --- /dev/null +++ b/tests/purs/docs/output/MultiVirtual/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"MultiVirtual","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/MultiVirtual/externs.cbor b/tests/purs/docs/output/MultiVirtual/externs.cbor new file mode 100644 index 000000000..9eabf0d2c Binary files /dev/null and b/tests/purs/docs/output/MultiVirtual/externs.cbor differ diff --git a/tests/purs/docs/output/MultiVirtual1/docs.json b/tests/purs/docs/output/MultiVirtual1/docs.json new file mode 100644 index 000000000..4bce7c214 --- /dev/null +++ b/tests/purs/docs/output/MultiVirtual1/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[3,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/MultiVirtual1.purs","start":[3,1]},"title":"foo"}],"name":"MultiVirtual1","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/MultiVirtual1/externs.cbor b/tests/purs/docs/output/MultiVirtual1/externs.cbor new file mode 100644 index 000000000..878d80167 Binary files /dev/null and b/tests/purs/docs/output/MultiVirtual1/externs.cbor differ diff --git a/tests/purs/docs/output/MultiVirtual2/docs.json b/tests/purs/docs/output/MultiVirtual2/docs.json new file mode 100644 index 000000000..a273f8840 --- /dev/null +++ b/tests/purs/docs/output/MultiVirtual2/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[8,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/MultiVirtual2.purs","start":[8,1]},"title":"bar"}],"name":"MultiVirtual2","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/MultiVirtual2/externs.cbor b/tests/purs/docs/output/MultiVirtual2/externs.cbor new file mode 100644 index 000000000..600285115 Binary files /dev/null and b/tests/purs/docs/output/MultiVirtual2/externs.cbor differ diff --git a/tests/purs/docs/output/MultiVirtual3/docs.json b/tests/purs/docs/output/MultiVirtual3/docs.json new file mode 100644 index 000000000..9e5faf55a --- /dev/null +++ b/tests/purs/docs/output/MultiVirtual3/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[3,11],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/MultiVirtual3.purs","start":[3,1]},"title":"baz"}],"name":"MultiVirtual3","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/MultiVirtual3/externs.cbor b/tests/purs/docs/output/MultiVirtual3/externs.cbor new file mode 100644 index 000000000..e5c6a14a7 Binary files /dev/null and b/tests/purs/docs/output/MultiVirtual3/externs.cbor differ diff --git a/tests/purs/docs/output/NewOperators/docs.json b/tests/purs/docs/output/NewOperators/docs.json new file mode 100644 index 000000000..af17c5000 --- /dev/null +++ b/tests/purs/docs/output/NewOperators/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"NewOperators","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/NewOperators/externs.cbor b/tests/purs/docs/output/NewOperators/externs.cbor new file mode 100644 index 000000000..254a70467 Binary files /dev/null and b/tests/purs/docs/output/NewOperators/externs.cbor differ diff --git a/tests/purs/docs/output/NewOperators2/docs.json b/tests/purs/docs/output/NewOperators2/docs.json new file mode 100644 index 000000000..b35cbd56c --- /dev/null +++ b/tests/purs/docs/output/NewOperators2/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"alias":[["NewOperators2"],{"Right":{"Left":{"Ident":"_compose"}}}],"declType":"alias","fixity":{"associativity":"infixl","precedence":8}},"kind":null,"sourceSpan":{"end":[3,25],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/NewOperators2.purs","start":[3,1]},"title":"(>>>)"},{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"b","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"c","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":"c","tag":"TypeVar"}],"tag":"TypeApp"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":"c","tag":"TypeVar"}],"tag":"TypeApp"},"tag":"ParensInType"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[5,59],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/NewOperators2.purs","start":[5,1]},"title":"_compose"}],"name":"NewOperators2","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/NewOperators2/externs.cbor b/tests/purs/docs/output/NewOperators2/externs.cbor new file mode 100644 index 000000000..8aab6236a Binary files /dev/null and b/tests/purs/docs/output/NewOperators2/externs.cbor differ diff --git a/tests/purs/docs/output/NotAllCtors/docs.json b/tests/purs/docs/output/NotAllCtors/docs.json new file mode 100644 index 000000000..e81e9b947 --- /dev/null +++ b/tests/purs/docs/output/NotAllCtors/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"NotAllCtors","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/NotAllCtors/externs.cbor b/tests/purs/docs/output/NotAllCtors/externs.cbor new file mode 100644 index 000000000..ae2d59d82 Binary files /dev/null and b/tests/purs/docs/output/NotAllCtors/externs.cbor differ diff --git a/tests/purs/docs/output/OperatorSection/docs.json b/tests/purs/docs/output/OperatorSection/docs.json new file mode 100644 index 000000000..ab1f932f9 --- /dev/null +++ b/tests/purs/docs/output/OperatorSection/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[3,18],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/OperatorSection.purs","start":[3,13]},"title":"Nil"},{"comments":null,"info":{"arguments":[{"annotation":[],"contents":"a","tag":"TypeVar"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[["OperatorSection"],"List"],"tag":"TypeConstructor"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"tag":"ParensInType"}],"declType":"dataConstructor"},"sourceSpan":{"end":[3,25],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/OperatorSection.purs","start":[3,19]},"title":"Cons"},{"comments":null,"info":{"declType":"instance","dependencies":[],"type":{"annotation":[],"contents":[{"annotation":[],"contents":[["OperatorSection"],"Foldable"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["OperatorSection"],"List"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[16,21],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/OperatorSection.purs","start":[10,1]},"title":""}],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Representational"],"typeArguments":[["a",null]]},"kind":null,"sourceSpan":{"end":[3,36],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/OperatorSection.purs","start":[3,1]},"title":"List"},{"children":[],"comments":null,"info":{"alias":[["OperatorSection"],{"Right":{"Right":"Cons"}}],"declType":"alias","fixity":{"associativity":"infixr","precedence":6}},"kind":null,"sourceSpan":{"end":[5,19],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/OperatorSection.purs","start":[5,1]},"title":"(:)"},{"children":[{"comments":null,"info":{"declType":"typeClassMember","type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"b","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":"f","tag":"TypeVar"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"sourceSpan":{"end":[8,54],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/OperatorSection.purs","start":[8,3]},"title":"foldl"},{"comments":null,"info":{"declType":"instance","dependencies":[],"type":{"annotation":[],"contents":[{"annotation":[],"contents":[["OperatorSection"],"Foldable"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["OperatorSection"],"List"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[16,21],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/OperatorSection.purs","start":[10,1]},"title":""}],"comments":null,"info":{"arguments":[["f",null]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":{"keyword":"class","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Constraint"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[8,54],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/OperatorSection.purs","start":[7,1]},"title":"Foldable"}],"name":"OperatorSection","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/OperatorSection/externs.cbor b/tests/purs/docs/output/OperatorSection/externs.cbor new file mode 100644 index 000000000..c3acf5342 Binary files /dev/null and b/tests/purs/docs/output/OperatorSection/externs.cbor differ diff --git a/tests/purs/docs/output/Prelude/docs.json b/tests/purs/docs/output/Prelude/docs.json new file mode 100644 index 000000000..7f58206cc --- /dev/null +++ b/tests/purs/docs/output/Prelude/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[],"tag":"REmpty"}],"tag":"TypeApp"}],"declType":"dataConstructor"},"sourceSpan":{"end":[3,23],"name":"bower_components/purescript-prelude/src/Prelude.purs","start":[3,14]},"title":"Unit"}],"comments":null,"info":{"dataDeclType":"newtype","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[3,23],"name":"bower_components/purescript-prelude/src/Prelude.purs","start":[3,1]},"title":"Unit"},{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prelude"],"Unit"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[5,13],"name":"bower_components/purescript-prelude/src/Prelude.purs","start":[5,1]},"title":"unit"},{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[8,21],"name":"bower_components/purescript-prelude/src/Prelude.purs","start":[8,15]},"title":"True"},{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[8,29],"name":"bower_components/purescript-prelude/src/Prelude.purs","start":[8,22]},"title":"False"}],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[8,29],"name":"bower_components/purescript-prelude/src/Prelude.purs","start":[8,1]},"title":"Boolean2"}],"name":"Prelude","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Prelude/externs.cbor b/tests/purs/docs/output/Prelude/externs.cbor new file mode 100644 index 000000000..fea0cc416 Binary files /dev/null and b/tests/purs/docs/output/Prelude/externs.cbor differ diff --git a/tests/purs/docs/output/Prim.Boolean/docs.json b/tests/purs/docs/output/Prim.Boolean/docs.json new file mode 100644 index 000000000..c98a89d5d --- /dev/null +++ b/tests/purs/docs/output/Prim.Boolean/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Boolean module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains a type level `Boolean` data structure.","declarations":[{"children":[],"comments":"The 'True' boolean type.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"True"},{"children":[],"comments":"The 'False' boolean type.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"False"}],"name":"Prim.Boolean","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Prim.Coerce/docs.json b/tests/purs/docs/output/Prim.Coerce/docs.json new file mode 100644 index 000000000..b05ecf299 --- /dev/null +++ b/tests/purs/docs/output/Prim.Coerce/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Coerce module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains an automatically solved type class for coercing types that have provably-identical runtime representations with [purescript-safe-coerce](https://pursuit.purescript.org/packages/purescript-safe-coerce).","declarations":[{"children":[],"comments":"Coercible is a two-parameter type class that has instances for types `a`\nand `b` if the compiler can infer that they have the same representation.\nCoercible constraints are solved according to the following rules:\n\n* _reflexivity_, any type has the same representation as itself:\n`Coercible a a` holds.\n\n* _symmetry_, if a type `a` can be coerced to some other type `b`, then `b`\ncan also be coerced back to `a`: `Coercible a b` implies `Coercible b a`.\n\n* _transitivity_, if a type `a` can be coerced to some other type `b` which\ncan be coerced to some other type `c`, then `a` can also be coerced to `c`:\n`Coercible a b` and `Coercible b c` imply `Coercible a c`.\n\n* Newtypes can be freely wrapped and unwrapped when their constructor is\nin scope:\n\n newtype Age = Age Int\n\n`Coercible Int Age` and `Coercible Age Int` hold since `Age` has the same\nruntime representation than `Int`.\n\nNewtype constructors have to be in scope to preserve abstraction. It's\ncommon to declare a newtype to encode some invariants (non emptiness of\narrays with `Data.Array.NonEmpty.NonEmptyArray` for example), hide its\nconstructor and export smart constructors instead. Without this restriction,\nthe guarantees provided by such newtypes would be void.\n\n* If none of the above are applicable, two types of kind `Type` may be\ncoercible, but only if their heads are the same. For example,\n`Coercible (Maybe a) (Either a b)` does not hold because `Maybe` and\n`Either` are different. Those types don't share a common runtime\nrepresentation so coercing between them would be unsafe. In addition their\narguments may need to be identical or coercible, depending on the _roles_\nof the head's type parameters. Roles are documented in [the PureScript\nlanguage reference](https://github.com/purescript/documentation/blob/master/language/Roles.md).\n\nCoercible being polykinded, we can also coerce more than types of kind `Type`:\n\n* Rows are coercible when they have the same labels, when the corresponding\npairs of types are coercible and when their tails are coercible:\n`Coercible ( label :: a | r ) ( label :: b | s )` holds when\n`Coercible a b` and `Coercible r s` do. Closed rows cannot be coerced to\nopen rows.\n\n* Higher kinded types are coercible if they are coercible when fully\nsaturated: `Coercible (f :: _ -> Type) (g :: _ -> Type)` holds when\n`Coercible (f a) (g a)` does.\n\nThis rule may seem puzzling since there is no term of type `_ -> Type` to\napply `coerce` to, but it is necessary when coercing types with higher\nkinded parameters.\n","info":{"arguments":[["a",{"annotation":[],"contents":"k","tag":"TypeVar"}],["b",{"annotation":[],"contents":"k","tag":"TypeVar"}]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Coercible"}],"name":"Prim.Coerce","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Prim.Int/docs.json b/tests/purs/docs/output/Prim.Int/docs.json new file mode 100644 index 000000000..ddd7dbd32 --- /dev/null +++ b/tests/purs/docs/output/Prim.Int/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Int module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains automatically solved type classes for working with type-level intural numbers.","declarations":[{"children":[],"comments":"Compiler solved type class for adding type-level `Int`s.\n","info":{"arguments":[["left",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["right",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["sum",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["left","right"],["sum"]],[["left","sum"],["right"]],[["right","sum"],["left"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Add"},{"children":[],"comments":"Compiler solved type class for comparing two type-level `Int`s.\nProduces an `Ordering`.\n","info":{"arguments":[["left",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["right",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["ordering",{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["left","right"],["ordering"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Compare"},{"children":[],"comments":"Compiler solved type class for multiplying type-level `Int`s.\n","info":{"arguments":[["left",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["right",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["product",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["left","right"],["product"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Mul"},{"children":[],"comments":"Compiler solved type class for converting a type-level `Int` into a type-level `String` (i.e. `Symbol`).\n","info":{"arguments":[["int",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["string",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["int"],["string"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"ToString"}],"name":"Prim.Int","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Prim.Ordering/docs.json b/tests/purs/docs/output/Prim.Ordering/docs.json new file mode 100644 index 000000000..48e6b141f --- /dev/null +++ b/tests/purs/docs/output/Prim.Ordering/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Ordering module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains a type level `Ordering` data structure.","declarations":[{"children":[],"comments":"The `Ordering` kind represents the three possibilities of comparing two\ntypes of the same kind: `LT` (less than), `EQ` (equal to), and\n`GT` (greater than).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Ordering"},{"children":[],"comments":"The 'less than' ordering type.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"LT"},{"children":[],"comments":"The 'equal to' ordering type.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"EQ"},{"children":[],"comments":"The 'greater than' ordering type.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"GT"}],"name":"Prim.Ordering","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Prim.Row/docs.json b/tests/purs/docs/output/Prim.Row/docs.json new file mode 100644 index 000000000..081b2d363 --- /dev/null +++ b/tests/purs/docs/output/Prim.Row/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Row module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains automatically solved type classes for working with row types.","declarations":[{"children":[],"comments":"The Union type class is used to compute the union of two rows of types\n(left-biased, including duplicates).\n\nThe third type argument represents the union of the first two.\n","info":{"arguments":[["left",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],["right",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],["union",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}]],"declType":"typeClass","fundeps":[[["left","right"],["union"]],[["right","union"],["left"]],[["union","left"],["right"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Union"},{"children":[],"comments":"The Nub type class is used to remove duplicate labels from rows.\n","info":{"arguments":[["original",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],["nubbed",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}]],"declType":"typeClass","fundeps":[[["original"],["nubbed"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Nub"},{"children":[],"comments":"The Lacks type class asserts that a label does not occur in a given row.\n","info":{"arguments":[["label",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["row",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Lacks"},{"children":[],"comments":"The Cons type class is a 4-way relation which asserts that one row of\ntypes can be obtained from another by inserting a new label/type pair on\nthe left.\n","info":{"arguments":[["label",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["a",{"annotation":[],"contents":"k","tag":"TypeVar"}],["tail",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],["row",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}]],"declType":"typeClass","fundeps":[[["label","a","tail"],["row"]],[["label","row"],["a","tail"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Cons"}],"name":"Prim.Row","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Prim.RowList/docs.json b/tests/purs/docs/output/Prim.RowList/docs.json new file mode 100644 index 000000000..1ea89a442 --- /dev/null +++ b/tests/purs/docs/output/Prim.RowList/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.RowList module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains a type level list (`RowList`) that represents an ordered view of a row of types.","declarations":[{"children":[],"comments":"A type level list representation of a row of types.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"RowList"},{"children":[],"comments":"Constructs a new `RowList` from a label, a type, and an existing tail\n`RowList`. E.g: `Cons \"x\" Int (Cons \"y\" Int Nil)`.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":{"identifier":"k","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim","RowList"],"RowList"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim","RowList"],"RowList"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Cons"},{"children":[],"comments":"The empty `RowList`.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":{"identifier":"k","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim","RowList"],"RowList"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Nil"},{"children":[],"comments":"Compiler solved type class for generating a `RowList` from a closed row\nof types. Entries are sorted by label and duplicates are preserved in\nthe order they appeared in the row.\n","info":{"arguments":[["row",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],["list",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim","RowList"],"RowList"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}]],"declType":"typeClass","fundeps":[[["row"],["list"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"RowToList"}],"name":"Prim.RowList","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Prim.Symbol/docs.json b/tests/purs/docs/output/Prim.Symbol/docs.json new file mode 100644 index 000000000..e2bc9ff2a --- /dev/null +++ b/tests/purs/docs/output/Prim.Symbol/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Symbol module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains automatically solved type classes for working with `Symbols`.","declarations":[{"children":[],"comments":"Compiler solved type class for appending `Symbol`s together.\n","info":{"arguments":[["left",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["right",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["appended",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["left","right"],["appended"]],[["right","appended"],["left"]],[["appended","left"],["right"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Append"},{"children":[],"comments":"Compiler solved type class for comparing two `Symbol`s.\nProduces an `Ordering`.\n","info":{"arguments":[["left",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["right",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["ordering",{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["left","right"],["ordering"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Compare"},{"children":[],"comments":"Compiler solved type class for either splitting up a symbol into its\nhead and tail or for combining a head and tail into a new symbol.\nRequires the head to be a single character and the combined string\ncannot be empty.\n","info":{"arguments":[["head",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["tail",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["symbol",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["head","tail"],["symbol"]],[["symbol"],["head","tail"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Cons"}],"name":"Prim.Symbol","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Prim.TypeError/docs.json b/tests/purs/docs/output/Prim.TypeError/docs.json new file mode 100644 index 000000000..86ca13721 --- /dev/null +++ b/tests/purs/docs/output/Prim.TypeError/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.TypeError module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains type classes that provide custom type error and warning functionality.","declarations":[{"children":[],"comments":"The Warn type class allows a custom compiler warning to be displayed.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"arguments":[["message",{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Warn"},{"children":[],"comments":"The Fail type class is part of the custom type errors feature. To provide\na custom type error when someone tries to use a particular instance,\nwrite that instance out with a Fail constraint.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"arguments":[["message",{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Fail"},{"children":[],"comments":"`Doc` is the kind of type-level documents.\n\nThis kind is used with the `Fail` and `Warn` type classes.\nBuild up a `Doc` with `Text`, `Quote`, `QuoteLabel`, `Beside`, and `Above`.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Doc"},{"children":[],"comments":"The Text type constructor makes a Doc from a Symbol\nto be used in a custom type error.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Text"},{"children":[],"comments":"The Quote type constructor renders any concrete type as a Doc\nto be used in a custom type error.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":{"identifier":"k","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Quote"},{"children":[],"comments":"The `QuoteLabel` type constructor will produce a `Doc` when given a `Symbol`. When the resulting `Doc` is rendered\nfor a `Warn` or `Fail` constraint, a syntactically valid label will be produced, escaping with quotes as needed.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"QuoteLabel"},{"children":[],"comments":"The Beside type constructor combines two Docs horizontally\nto be used in a custom type error.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Beside"},{"children":[],"comments":"The Above type constructor combines two Docs vertically\nin a custom type error.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Above"}],"name":"Prim.TypeError","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Prim/docs.json b/tests/purs/docs/output/Prim/docs.json new file mode 100644 index 000000000..8a8ee9e8a --- /dev/null +++ b/tests/purs/docs/output/Prim/docs.json @@ -0,0 +1 @@ +{"comments":"The `Prim` module is embedded in the PureScript compiler in order to provide compiler support for certain types — for example, value literals, or syntax sugar. It is implicitly imported unqualified in every module except those that list it as a qualified import.\n\n`Prim` does not include additional built-in types and kinds that are defined deeper in the compiler such as Type wildcards (e.g. `f :: _ -> Int`) and Quantified Types. Rather, these are documented in [the PureScript language reference](https://github.com/purescript/documentation/blob/master/language/Types.md).\n","declarations":[{"children":[],"comments":"A function, which takes values of the type specified by the first type\nparameter, and returns values of the type specified by the second.\nIn the JavaScript backend, this is a standard JavaScript Function.\n\nThe type constructor `(->)` is syntactic sugar for this type constructor.\nIt is recommended to use `(->)` rather than `Function`, where possible.\n\nThat is, prefer this:\n\n f :: Number -> Number\n\nto either of these:\n\n f :: Function Number Number\n f :: (->) Number Number\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Function"},{"children":[],"comments":"An Array: a data structure supporting efficient random access. In\nthe JavaScript backend, values of this type are represented as JavaScript\nArrays at runtime.\n\nConstruct values using literals:\n\n x = [1,2,3,4,5] :: Array Int\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Array"},{"children":[],"comments":"The type of records whose fields are known at compile time. In the\nJavaScript backend, values of this type are represented as JavaScript\nObjects at runtime.\n\nThe type signature here means that the `Record` type constructor takes\na row of concrete types. For example:\n\n type Person = Record (name :: String, age :: Number)\n\nThe syntactic sugar with curly braces `{ }` is generally preferred, though:\n\n type Person = { name :: String, age :: Number }\n\nThe row associates a type to each label which appears in the record.\n\n_Technical note_: PureScript allows duplicate labels in rows, and the\nmeaning of `Record r` is based on the _first_ occurrence of each label in\nthe row `r`.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Record"},{"children":[],"comments":"A double precision floating point number (IEEE 754).\n\nConstruct values of this type with literals.\nNegative literals must be wrapped in parentheses if the negation sign could be mistaken\nfor an infix operator:\n\n x = 35.23 :: Number\n y = -1.224e6 :: Number\n z = exp (-1.0) :: Number\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Number"},{"children":[],"comments":"A 32-bit signed integer. See the `purescript-integers` package for details\nof how this is accomplished when compiling to JavaScript.\n\nConstruct values of this type with literals. Hexadecimal syntax is supported.\nNegative literals must be wrapped in parentheses if the negation sign could be mistaken\nfor an infix operator:\n\n x = -23 :: Int\n y = 0x17 :: Int\n z = complement (-24) :: Int\n\nIntegers used as types are considered to have kind `Int`.\nUnlike value-level `Int`s, which must be representable as a 32-bit signed integer,\ntype-level `Int`s are unbounded. Hexadecimal support is also supported at the type level.\n\n type One :: Int\n type One = 1\n \n type Beyond32BitSignedInt :: Int\n type Beyond32BitSignedInt = 2147483648\n \n type HexInt :: Int\n type HexInt = 0x17\n\nNegative integer literals at the type level must be\nwrapped in parentheses if the negation sign could be mistaken for an infix operator.\n\n type NegativeOne = -1\n foo :: Proxy (-1) -> ...\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Int"},{"children":[],"comments":"A String. As in JavaScript, String values represent sequences of UTF-16\ncode units, which are not required to form a valid encoding of Unicode\ntext (for example, lone surrogates are permitted).\n\nConstruct values of this type with literals, using double quotes `\"`:\n\n x = \"hello, world\" :: String\n\nMulti-line string literals are also supported with triple quotes (`\"\"\"`):\n\n x = \"\"\"multi\n line\"\"\"\n\nAt the type level, string literals represent types with kind `Symbol`.\nThese types will have kind `String` in a future release:\n\n type Hello :: Symbol\n type Hello = \"Hello, world\"\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"String"},{"children":[],"comments":"A single character (UTF-16 code unit). The JavaScript representation is a\nnormal `String`, which is guaranteed to contain one code unit. This means\nthat astral plane characters (i.e. those with code point values greater\nthan `0xFFFF`) cannot be represented as `Char` values.\n\nConstruct values of this type with literals, using single quotes `'`:\n\n x = 'a' :: Char\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Char"},{"children":[],"comments":"A JavaScript Boolean value.\n\nConstruct values of this type with the literals `true` and `false`.\n\nThe `True` and `False` types defined in `Prim.Boolean` have this type as their kind.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Boolean"},{"children":[],"comments":"The Partial type class is used to indicate that a function is *partial,*\nthat is, it is not defined for all inputs. In practice, attempting to use\na partial function with a bad input will usually cause an error to be\nthrown, although it is not safe to assume that this will happen in all\ncases. For more information, see\n[purescript-partial](https://pursuit.purescript.org/packages/purescript-partial/).\n","info":{"arguments":[],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Partial"},{"children":[],"comments":"`Type` is the kind of all proper types: those that classify value-level terms.\nFor example the type `Boolean` has kind `Type`; denoted by `Boolean :: Type`.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Type"},{"children":[],"comments":"`Constraint` is the kind of type class constraints.\nFor example, a type class declaration like this:\n\n class Semigroup a where\n append :: a -> a -> a\n\nhas the kind signature:\n\n class Semigroup :: Type -> Constraint\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Constraint"},{"children":[],"comments":"`Symbol` is the kind of type-level strings.\n\nConstruct types of this kind using the same literal syntax as documented\nfor strings.\n\n type Hello :: Symbol\n type Hello = \"Hello, world\"\n\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Symbol"},{"children":[],"comments":"`Row` is the kind constructor of label-indexed types which map type-level strings to other types.\nThe most common use of `Row` is `Row Type`, a row mapping labels to basic (of kind `Type`) types:\n\n type ExampleRow :: Row Type\n type ExampleRow = ( name :: String, values :: Array Int )\n\nThis is the kind of `Row` expected by the `Record` type constructor.\nMore advanced row kinds like `Row (Type -> Type)` are used much less frequently.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Row"}],"name":"Prim","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/PrimSubmodules/docs.json b/tests/purs/docs/output/PrimSubmodules/docs.json new file mode 100644 index 000000000..997894766 --- /dev/null +++ b/tests/purs/docs/output/PrimSubmodules/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[{"comments":null,"info":{"arguments":[{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"declType":"dataConstructor"},"sourceSpan":{"end":[5,33],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/PrimSubmodules.purs","start":[5,28]},"title":"Lol"}],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Phantom"],"typeArguments":[["a",{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"}]]},"kind":{"keyword":"data","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[5,37],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/PrimSubmodules.purs","start":[5,1]},"title":"Lol"},{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[{"annotation":[],"contents":[["PrimSubmodules"],"Lol"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim","Ordering"],"LT"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":null,"sourceSpan":{"end":[7,14],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/PrimSubmodules.purs","start":[7,1]},"title":"x"},{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[{"annotation":[],"contents":[["PrimSubmodules"],"Lol"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim","Ordering"],"EQ"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":null,"sourceSpan":{"end":[10,14],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/PrimSubmodules.purs","start":[10,1]},"title":"y"}],"name":"PrimSubmodules","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/PrimSubmodules/externs.cbor b/tests/purs/docs/output/PrimSubmodules/externs.cbor new file mode 100644 index 000000000..b1d5370b3 Binary files /dev/null and b/tests/purs/docs/output/PrimSubmodules/externs.cbor differ diff --git a/tests/purs/docs/output/ReExportedTypeClass/docs.json b/tests/purs/docs/output/ReExportedTypeClass/docs.json new file mode 100644 index 000000000..8e58c1266 --- /dev/null +++ b/tests/purs/docs/output/ReExportedTypeClass/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"ReExportedTypeClass","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/ReExportedTypeClass/externs.cbor b/tests/purs/docs/output/ReExportedTypeClass/externs.cbor new file mode 100644 index 000000000..af14223b9 Binary files /dev/null and b/tests/purs/docs/output/ReExportedTypeClass/externs.cbor differ diff --git a/tests/purs/docs/output/RoleAnnotationDocs/docs.json b/tests/purs/docs/output/RoleAnnotationDocs/docs.json new file mode 100644 index 000000000..cc36f7aa1 --- /dev/null +++ b/tests/purs/docs/output/RoleAnnotationDocs/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[3,25],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[3,18]},"title":"D_RNP"}],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Representational","Nominal","Phantom"],"typeArguments":[["a",null],["b",null],["c",null]]},"kind":{"keyword":"data","kind":{"annotation":[],"contents":{"identifier":"k1","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"k2","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"k3","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k1","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k2","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k3","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"sourceSpan":{"end":[3,25],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[3,1]},"title":"D_RNP"},{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[6,25],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[6,18]},"title":"D_NPR"}],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Nominal","Phantom","Representational"],"typeArguments":[["a",null],["b",null],["c",null]]},"kind":{"keyword":"data","kind":{"annotation":[],"contents":{"identifier":"k1","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"k2","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"k3","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k1","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k2","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k3","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"sourceSpan":{"end":[6,25],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[6,1]},"title":"D_NPR"},{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[9,25],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[9,18]},"title":"D_PRN"}],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Phantom","Representational","Nominal"],"typeArguments":[["a",null],["b",null],["c",null]]},"kind":{"keyword":"data","kind":{"annotation":[],"contents":{"identifier":"k1","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"k2","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"k3","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k1","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k2","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k3","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"sourceSpan":{"end":[9,25],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[9,1]},"title":"D_PRN"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Nominal","Nominal","Nominal"],"typeArguments":[["t0",null],["t1",null],["t2",null]]},"kind":null,"sourceSpan":{"end":[12,60],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[12,1]},"title":"FFI_NNN"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Representational","Nominal","Phantom"],"typeArguments":[["t0",null],["t1",null],["t2",null]]},"kind":null,"sourceSpan":{"end":[14,60],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[14,1]},"title":"FFI_RNP"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Representational","Nominal","Phantom"],"typeArguments":[["t0",null],["t1",null],["t2",null]]},"kind":{"keyword":"data","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"sourceSpan":{"end":[17,74],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[17,1]},"title":"FFI_Higher1"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Representational","Nominal","Phantom"],"typeArguments":[["t0",null],["t1",null],["t2",null]]},"kind":{"keyword":"data","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"sourceSpan":{"end":[20,74],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[20,1]},"title":"FFI_Higher2"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Representational","Nominal","Phantom"],"typeArguments":[["t0",null],["t1",null],["t2",null]]},"kind":{"keyword":"data","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"sourceSpan":{"end":[23,74],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[23,1]},"title":"FFI_Higher3"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Representational","Nominal","Phantom"],"typeArguments":[["t0",null],["t1",null],["t2",null]]},"kind":{"keyword":"data","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"tag":"ParensInType"}],"tag":"TypeApp"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"sourceSpan":{"end":[26,84],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[26,1]},"title":"FFI_Higher4"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Representational","Nominal","Phantom"],"typeArguments":[["t0",null],["t1",null],["t2",null]]},"kind":null,"sourceSpan":{"end":[29,69],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[29,1]},"title":"FFI_HeadParens"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Representational","Nominal","Phantom"],"typeArguments":[["t0",null],["t1",null],["t2",null]]},"kind":null,"sourceSpan":{"end":[32,69],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[32,1]},"title":"FFI_TailParens"},{"children":[],"comments":null,"info":{"dataDeclType":"data","declType":"data","roles":["Representational","Nominal","Phantom"],"typeArguments":[["t0",null],["t1",null],["t2",null]]},"kind":null,"sourceSpan":{"end":[35,70],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/RoleAnnotationDocs.purs","start":[35,1]},"title":"FFI_WholeParens"}],"name":"RoleAnnotationDocs","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/RoleAnnotationDocs/externs.cbor b/tests/purs/docs/output/RoleAnnotationDocs/externs.cbor new file mode 100644 index 000000000..b24fe45fb Binary files /dev/null and b/tests/purs/docs/output/RoleAnnotationDocs/externs.cbor differ diff --git a/tests/purs/docs/output/Shebang1Undocumented/docs.json b/tests/purs/docs/output/Shebang1Undocumented/docs.json new file mode 100644 index 000000000..3f932ff23 --- /dev/null +++ b/tests/purs/docs/output/Shebang1Undocumented/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"Shebang1Undocumented","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Shebang1Undocumented/externs.cbor b/tests/purs/docs/output/Shebang1Undocumented/externs.cbor new file mode 100644 index 000000000..8b32266ac Binary files /dev/null and b/tests/purs/docs/output/Shebang1Undocumented/externs.cbor differ diff --git a/tests/purs/docs/output/Shebang2Undocumented/docs.json b/tests/purs/docs/output/Shebang2Undocumented/docs.json new file mode 100644 index 000000000..6f8b85418 --- /dev/null +++ b/tests/purs/docs/output/Shebang2Undocumented/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"Shebang2Undocumented","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Shebang2Undocumented/externs.cbor b/tests/purs/docs/output/Shebang2Undocumented/externs.cbor new file mode 100644 index 000000000..27886059f Binary files /dev/null and b/tests/purs/docs/output/Shebang2Undocumented/externs.cbor differ diff --git a/tests/purs/docs/output/Shebang3Undocumented/docs.json b/tests/purs/docs/output/Shebang3Undocumented/docs.json new file mode 100644 index 000000000..336925e7e --- /dev/null +++ b/tests/purs/docs/output/Shebang3Undocumented/docs.json @@ -0,0 +1 @@ +{"comments":"Normal doc comment\n","declarations":[],"name":"Shebang3Undocumented","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Shebang3Undocumented/externs.cbor b/tests/purs/docs/output/Shebang3Undocumented/externs.cbor new file mode 100644 index 000000000..34225a263 Binary files /dev/null and b/tests/purs/docs/output/Shebang3Undocumented/externs.cbor differ diff --git a/tests/purs/docs/output/Shebang4Undocumented/docs.json b/tests/purs/docs/output/Shebang4Undocumented/docs.json new file mode 100644 index 000000000..c9c4729fd --- /dev/null +++ b/tests/purs/docs/output/Shebang4Undocumented/docs.json @@ -0,0 +1 @@ +{"comments":"Normal doc comment\n","declarations":[],"name":"Shebang4Undocumented","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Shebang4Undocumented/externs.cbor b/tests/purs/docs/output/Shebang4Undocumented/externs.cbor new file mode 100644 index 000000000..7a29351de Binary files /dev/null and b/tests/purs/docs/output/Shebang4Undocumented/externs.cbor differ diff --git a/tests/purs/docs/output/SolitaryTypeClassMember/docs.json b/tests/purs/docs/output/SolitaryTypeClassMember/docs.json new file mode 100644 index 000000000..85c3f288a --- /dev/null +++ b/tests/purs/docs/output/SolitaryTypeClassMember/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"SolitaryTypeClassMember","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/SolitaryTypeClassMember/externs.cbor b/tests/purs/docs/output/SolitaryTypeClassMember/externs.cbor new file mode 100644 index 000000000..e6771340f Binary files /dev/null and b/tests/purs/docs/output/SolitaryTypeClassMember/externs.cbor differ diff --git a/tests/purs/docs/output/SomeTypeClass/docs.json b/tests/purs/docs/output/SomeTypeClass/docs.json new file mode 100644 index 000000000..e35c68466 --- /dev/null +++ b/tests/purs/docs/output/SomeTypeClass/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[{"comments":null,"info":{"declType":"typeClassMember","type":{"annotation":[],"contents":"a","tag":"TypeVar"}},"sourceSpan":{"end":[5,14],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/SomeTypeClass.purs","start":[5,3]},"title":"member"}],"comments":null,"info":{"arguments":[["a",null]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":{"end":[5,14],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/SomeTypeClass.purs","start":[4,1]},"title":"SomeClass"}],"name":"SomeTypeClass","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/SomeTypeClass/externs.cbor b/tests/purs/docs/output/SomeTypeClass/externs.cbor new file mode 100644 index 000000000..0e2781cac Binary files /dev/null and b/tests/purs/docs/output/SomeTypeClass/externs.cbor differ diff --git a/tests/purs/docs/output/Transitive1/docs.json b/tests/purs/docs/output/Transitive1/docs.json new file mode 100644 index 000000000..5242e712f --- /dev/null +++ b/tests/purs/docs/output/Transitive1/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"Transitive1","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Transitive1/externs.cbor b/tests/purs/docs/output/Transitive1/externs.cbor new file mode 100644 index 000000000..0ba9ff3f1 Binary files /dev/null and b/tests/purs/docs/output/Transitive1/externs.cbor differ diff --git a/tests/purs/docs/output/Transitive2/docs.json b/tests/purs/docs/output/Transitive2/docs.json new file mode 100644 index 000000000..30edc30bf --- /dev/null +++ b/tests/purs/docs/output/Transitive2/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"Transitive2","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Transitive2/externs.cbor b/tests/purs/docs/output/Transitive2/externs.cbor new file mode 100644 index 000000000..35ff4cd8c Binary files /dev/null and b/tests/purs/docs/output/Transitive2/externs.cbor differ diff --git a/tests/purs/docs/output/Transitive3/docs.json b/tests/purs/docs/output/Transitive3/docs.json new file mode 100644 index 000000000..a641aeb10 --- /dev/null +++ b/tests/purs/docs/output/Transitive3/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[3,19],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/Transitive3.purs","start":[3,1]},"title":"transitive3"}],"name":"Transitive3","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Transitive3/externs.cbor b/tests/purs/docs/output/Transitive3/externs.cbor new file mode 100644 index 000000000..4e65b40b3 Binary files /dev/null and b/tests/purs/docs/output/Transitive3/externs.cbor differ diff --git a/tests/purs/docs/output/TypeClassWithoutMembers/docs.json b/tests/purs/docs/output/TypeClassWithoutMembers/docs.json new file mode 100644 index 000000000..a3fa17ce9 --- /dev/null +++ b/tests/purs/docs/output/TypeClassWithoutMembers/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"TypeClassWithoutMembers","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/TypeClassWithoutMembers/externs.cbor b/tests/purs/docs/output/TypeClassWithoutMembers/externs.cbor new file mode 100644 index 000000000..72e8d9ba0 Binary files /dev/null and b/tests/purs/docs/output/TypeClassWithoutMembers/externs.cbor differ diff --git a/tests/purs/docs/output/TypeClassWithoutMembersIntermediate/docs.json b/tests/purs/docs/output/TypeClassWithoutMembersIntermediate/docs.json new file mode 100644 index 000000000..91527f23e --- /dev/null +++ b/tests/purs/docs/output/TypeClassWithoutMembersIntermediate/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"TypeClassWithoutMembersIntermediate","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/TypeClassWithoutMembersIntermediate/externs.cbor b/tests/purs/docs/output/TypeClassWithoutMembersIntermediate/externs.cbor new file mode 100644 index 000000000..9510eb1e9 Binary files /dev/null and b/tests/purs/docs/output/TypeClassWithoutMembersIntermediate/externs.cbor differ diff --git a/tests/purs/docs/output/TypeSynonym/docs.json b/tests/purs/docs/output/TypeSynonym/docs.json new file mode 100644 index 000000000..30c14134c --- /dev/null +++ b/tests/purs/docs/output/TypeSynonym/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":null,"info":{"arguments":[],"declType":"typeSynonym","type":{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[3,17],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/TypeSynonym.purs","start":[3,1]},"title":"MyInt"}],"name":"TypeSynonym","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/TypeSynonym/externs.cbor b/tests/purs/docs/output/TypeSynonym/externs.cbor new file mode 100644 index 000000000..82954073f Binary files /dev/null and b/tests/purs/docs/output/TypeSynonym/externs.cbor differ diff --git a/tests/purs/docs/output/UTF8/docs.json b/tests/purs/docs/output/UTF8/docs.json new file mode 100644 index 000000000..b030f0329 --- /dev/null +++ b/tests/purs/docs/output/UTF8/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":"üÜäÄ 😰\n","info":{"declType":"value","type":{"annotation":[],"contents":[["Prelude"],"Unit"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[6,14],"name":"/home/gnumonik/code/work/purus/tests/purs/docs/src/UTF8.purs","start":[6,1]},"title":"thing"}],"name":"UTF8","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/UTF8/externs.cbor b/tests/purs/docs/output/UTF8/externs.cbor new file mode 100644 index 000000000..e7106600d Binary files /dev/null and b/tests/purs/docs/output/UTF8/externs.cbor differ diff --git a/tests/purs/docs/output/Virtual/docs.json b/tests/purs/docs/output/Virtual/docs.json new file mode 100644 index 000000000..ddca12e24 --- /dev/null +++ b/tests/purs/docs/output/Virtual/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[],"name":"Virtual","reExports":[]} \ No newline at end of file diff --git a/tests/purs/docs/output/Virtual/externs.cbor b/tests/purs/docs/output/Virtual/externs.cbor new file mode 100644 index 000000000..9602050ca Binary files /dev/null and b/tests/purs/docs/output/Virtual/externs.cbor differ diff --git a/tests/purs/docs/output/package.json b/tests/purs/docs/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purs/docs/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Data.Boolean/docs.json b/tests/purs/publish/basic-example/output/Data.Boolean/docs.json new file mode 100644 index 000000000..4b9dac24f --- /dev/null +++ b/tests/purs/publish/basic-example/output/Data.Boolean/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":"An alias for `true`, which can be useful in guard clauses:\n\n```purescript\nmax x y | x >= y = x\n | otherwise = y\n```\n","info":{"declType":"value","type":{"annotation":[],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[9,21],"name":"../../../support/bower_components/purescript-prelude/src/Data/Boolean.purs","start":[9,1]},"title":"otherwise"}],"name":"Data.Boolean","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Data.Boolean/externs.cbor b/tests/purs/publish/basic-example/output/Data.Boolean/externs.cbor new file mode 100644 index 000000000..bb86c4eb0 Binary files /dev/null and b/tests/purs/publish/basic-example/output/Data.Boolean/externs.cbor differ diff --git a/tests/purs/publish/basic-example/output/Data.NaturalTransformation/docs.json b/tests/purs/publish/basic-example/output/Data.NaturalTransformation/docs.json new file mode 100644 index 000000000..1a0d63b1f --- /dev/null +++ b/tests/purs/publish/basic-example/output/Data.NaturalTransformation/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":"A type for natural transformations.\n\nA natural transformation is a mapping between type constructors of kind\n`k -> Type`, for any kind `k`, where the mapping operation has no ability\nto manipulate the inner values.\n\nAn example of this is the `fromFoldable` function provided in\n`purescript-lists`, where some foldable structure containing values of\ntype `a` is converted into a `List a`.\n\nThe definition of a natural transformation in category theory states that\n`f` and `g` should be functors, but the `Functor` constraint is not\nenforced here; that the types are of kind `k -> Type` is enough for our\npurposes.\n","info":{"arguments":[["f",null],["g",null]],"declType":"typeSynonym","type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":"f","tag":"TypeVar"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":"g","tag":"TypeVar"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":{"keyword":"type","kind":{"annotation":[],"contents":{"identifier":"k","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"sourceSpan":{"end":[18,54],"name":"../../../support/bower_components/purescript-prelude/src/Data/NaturalTransformation.purs","start":[18,1]},"title":"NaturalTransformation"},{"children":[],"comments":null,"info":{"alias":[["Data","NaturalTransformation"],{"Left":"NaturalTransformation"}],"declType":"alias","fixity":{"associativity":"infixr","precedence":4}},"kind":null,"sourceSpan":{"end":[20,42],"name":"../../../support/bower_components/purescript-prelude/src/Data/NaturalTransformation.purs","start":[20,1]},"title":"type (~>)"}],"name":"Data.NaturalTransformation","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Data.NaturalTransformation/externs.cbor b/tests/purs/publish/basic-example/output/Data.NaturalTransformation/externs.cbor new file mode 100644 index 000000000..9f7bc8598 Binary files /dev/null and b/tests/purs/publish/basic-example/output/Data.NaturalTransformation/externs.cbor differ diff --git a/tests/purs/publish/basic-example/output/Data.Symbol/docs.json b/tests/purs/publish/basic-example/output/Data.Symbol/docs.json new file mode 100644 index 000000000..897b7f059 --- /dev/null +++ b/tests/purs/publish/basic-example/output/Data.Symbol/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[{"comments":null,"info":{"declType":"typeClassMember","type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Type","Proxy"],"Proxy"],"tag":"TypeConstructor"},{"annotation":[],"contents":"sym","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[11,39],"name":"../../../support/bower_components/purescript-prelude/src/Data/Symbol.purs","start":[11,3]},"title":"reflectSymbol"}],"comments":"A class for known symbols\n","info":{"arguments":[["sym",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":{"keyword":"class","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Constraint"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"sourceSpan":{"end":[11,39],"name":"../../../support/bower_components/purescript-prelude/src/Data/Symbol.purs","start":[10,1]},"title":"IsSymbol"},{"children":[],"comments":null,"info":{"declType":"value","type":{"annotation":[],"contents":{"identifier":"r","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":{"annotation":[],"contents":{"identifier":"sym","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"constraintAnn":[],"constraintArgs":[{"annotation":[],"contents":"sym","tag":"TypeVar"}],"constraintClass":[["Data","Symbol"],"IsSymbol"],"constraintData":null,"constraintKindArgs":[]},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Type","Proxy"],"Proxy"],"tag":"TypeConstructor"},{"annotation":[],"contents":"sym","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"ConstrainedType"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"tag":"ParensInType"}],"tag":"TypeApp"},{"annotation":[],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[16,85],"name":"../../../support/bower_components/purescript-prelude/src/Data/Symbol.purs","start":[16,1]},"title":"reifySymbol"}],"name":"Data.Symbol","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Data.Symbol/externs.cbor b/tests/purs/publish/basic-example/output/Data.Symbol/externs.cbor new file mode 100644 index 000000000..492076dc7 Binary files /dev/null and b/tests/purs/publish/basic-example/output/Data.Symbol/externs.cbor differ diff --git a/tests/purs/publish/basic-example/output/Data.Unit/docs.json b/tests/purs/publish/basic-example/output/Data.Unit/docs.json new file mode 100644 index 000000000..0298cd858 --- /dev/null +++ b/tests/purs/publish/basic-example/output/Data.Unit/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":"The `Unit` type has a single inhabitant, called `unit`. It represents\nvalues with no computational content.\n\n`Unit` is often used, wrapped in a monadic type constructor, as the\nreturn type of a computation where only the _effects_ are important.\n\nWhen returning a value of type `Unit` from an FFI function, it is\nrecommended to use `undefined`, or not return a value at all.\n","info":{"dataDeclType":"data","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[11,33],"name":"../../../support/bower_components/purescript-prelude/src/Data/Unit.purs","start":[11,1]},"title":"Unit"},{"children":[],"comments":"`unit` is the sole inhabitant of the `Unit` type.\n","info":{"declType":"value","type":{"annotation":[],"contents":[["Data","Unit"],"Unit"],"tag":"TypeConstructor"}},"kind":null,"sourceSpan":{"end":[14,28],"name":"../../../support/bower_components/purescript-prelude/src/Data/Unit.purs","start":[14,1]},"title":"unit"}],"name":"Data.Unit","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Data.Unit/externs.cbor b/tests/purs/publish/basic-example/output/Data.Unit/externs.cbor new file mode 100644 index 000000000..4df11d7e6 Binary files /dev/null and b/tests/purs/publish/basic-example/output/Data.Unit/externs.cbor differ diff --git a/tests/purs/publish/basic-example/output/Data.Void/docs.json b/tests/purs/publish/basic-example/output/Data.Void/docs.json new file mode 100644 index 000000000..cb068053e --- /dev/null +++ b/tests/purs/publish/basic-example/output/Data.Void/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":"An uninhabited data type. In other words, one can never create\na runtime value of type `Void` because no such value exists.\n\n`Void` is useful to eliminate the possibility of a value being created.\nFor example, a value of type `Either Void Boolean` can never have\na Left value created in PureScript.\n\nThis should not be confused with the keyword `void` that commonly appears in\nC-family languages, such as Java:\n```\npublic class Foo {\n void doSomething() { System.out.println(\"hello world!\"); }\n}\n```\n\nIn PureScript, one often uses `Unit` to achieve similar effects as\nthe `void` of C-family languages above.\n","info":{"dataDeclType":"newtype","declType":"data","roles":[],"typeArguments":[]},"kind":null,"sourceSpan":{"end":[20,25],"name":"../../../support/bower_components/purescript-prelude/src/Data/Void.purs","start":[20,1]},"title":"Void"},{"children":[],"comments":"Eliminator for the `Void` type.\nUseful for stating that some code branch is impossible because you've\n\"acquired\" a value of type `Void` (which you can't).\n\n```purescript\nrightOnly :: forall t . Either Void t -> t\nrightOnly (Left v) = absurd v\nrightOnly (Right t) = t\n```\n","info":{"declType":"value","type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Data","Void"],"Void"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[31,30],"name":"../../../support/bower_components/purescript-prelude/src/Data/Void.purs","start":[31,1]},"title":"absurd"}],"name":"Data.Void","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Data.Void/externs.cbor b/tests/purs/publish/basic-example/output/Data.Void/externs.cbor new file mode 100644 index 000000000..0e5571ef9 Binary files /dev/null and b/tests/purs/publish/basic-example/output/Data.Void/externs.cbor differ diff --git a/tests/purs/publish/basic-example/output/Prim.Boolean/docs.json b/tests/purs/publish/basic-example/output/Prim.Boolean/docs.json new file mode 100644 index 000000000..c98a89d5d --- /dev/null +++ b/tests/purs/publish/basic-example/output/Prim.Boolean/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Boolean module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains a type level `Boolean` data structure.","declarations":[{"children":[],"comments":"The 'True' boolean type.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"True"},{"children":[],"comments":"The 'False' boolean type.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"False"}],"name":"Prim.Boolean","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Prim.Coerce/docs.json b/tests/purs/publish/basic-example/output/Prim.Coerce/docs.json new file mode 100644 index 000000000..b05ecf299 --- /dev/null +++ b/tests/purs/publish/basic-example/output/Prim.Coerce/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Coerce module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains an automatically solved type class for coercing types that have provably-identical runtime representations with [purescript-safe-coerce](https://pursuit.purescript.org/packages/purescript-safe-coerce).","declarations":[{"children":[],"comments":"Coercible is a two-parameter type class that has instances for types `a`\nand `b` if the compiler can infer that they have the same representation.\nCoercible constraints are solved according to the following rules:\n\n* _reflexivity_, any type has the same representation as itself:\n`Coercible a a` holds.\n\n* _symmetry_, if a type `a` can be coerced to some other type `b`, then `b`\ncan also be coerced back to `a`: `Coercible a b` implies `Coercible b a`.\n\n* _transitivity_, if a type `a` can be coerced to some other type `b` which\ncan be coerced to some other type `c`, then `a` can also be coerced to `c`:\n`Coercible a b` and `Coercible b c` imply `Coercible a c`.\n\n* Newtypes can be freely wrapped and unwrapped when their constructor is\nin scope:\n\n newtype Age = Age Int\n\n`Coercible Int Age` and `Coercible Age Int` hold since `Age` has the same\nruntime representation than `Int`.\n\nNewtype constructors have to be in scope to preserve abstraction. It's\ncommon to declare a newtype to encode some invariants (non emptiness of\narrays with `Data.Array.NonEmpty.NonEmptyArray` for example), hide its\nconstructor and export smart constructors instead. Without this restriction,\nthe guarantees provided by such newtypes would be void.\n\n* If none of the above are applicable, two types of kind `Type` may be\ncoercible, but only if their heads are the same. For example,\n`Coercible (Maybe a) (Either a b)` does not hold because `Maybe` and\n`Either` are different. Those types don't share a common runtime\nrepresentation so coercing between them would be unsafe. In addition their\narguments may need to be identical or coercible, depending on the _roles_\nof the head's type parameters. Roles are documented in [the PureScript\nlanguage reference](https://github.com/purescript/documentation/blob/master/language/Roles.md).\n\nCoercible being polykinded, we can also coerce more than types of kind `Type`:\n\n* Rows are coercible when they have the same labels, when the corresponding\npairs of types are coercible and when their tails are coercible:\n`Coercible ( label :: a | r ) ( label :: b | s )` holds when\n`Coercible a b` and `Coercible r s` do. Closed rows cannot be coerced to\nopen rows.\n\n* Higher kinded types are coercible if they are coercible when fully\nsaturated: `Coercible (f :: _ -> Type) (g :: _ -> Type)` holds when\n`Coercible (f a) (g a)` does.\n\nThis rule may seem puzzling since there is no term of type `_ -> Type` to\napply `coerce` to, but it is necessary when coercing types with higher\nkinded parameters.\n","info":{"arguments":[["a",{"annotation":[],"contents":"k","tag":"TypeVar"}],["b",{"annotation":[],"contents":"k","tag":"TypeVar"}]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Coercible"}],"name":"Prim.Coerce","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Prim.Int/docs.json b/tests/purs/publish/basic-example/output/Prim.Int/docs.json new file mode 100644 index 000000000..ddd7dbd32 --- /dev/null +++ b/tests/purs/publish/basic-example/output/Prim.Int/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Int module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains automatically solved type classes for working with type-level intural numbers.","declarations":[{"children":[],"comments":"Compiler solved type class for adding type-level `Int`s.\n","info":{"arguments":[["left",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["right",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["sum",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["left","right"],["sum"]],[["left","sum"],["right"]],[["right","sum"],["left"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Add"},{"children":[],"comments":"Compiler solved type class for comparing two type-level `Int`s.\nProduces an `Ordering`.\n","info":{"arguments":[["left",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["right",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["ordering",{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["left","right"],["ordering"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Compare"},{"children":[],"comments":"Compiler solved type class for multiplying type-level `Int`s.\n","info":{"arguments":[["left",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["right",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["product",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["left","right"],["product"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Mul"},{"children":[],"comments":"Compiler solved type class for converting a type-level `Int` into a type-level `String` (i.e. `Symbol`).\n","info":{"arguments":[["int",{"annotation":[],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],["string",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["int"],["string"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"ToString"}],"name":"Prim.Int","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Prim.Ordering/docs.json b/tests/purs/publish/basic-example/output/Prim.Ordering/docs.json new file mode 100644 index 000000000..48e6b141f --- /dev/null +++ b/tests/purs/publish/basic-example/output/Prim.Ordering/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Ordering module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains a type level `Ordering` data structure.","declarations":[{"children":[],"comments":"The `Ordering` kind represents the three possibilities of comparing two\ntypes of the same kind: `LT` (less than), `EQ` (equal to), and\n`GT` (greater than).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Ordering"},{"children":[],"comments":"The 'less than' ordering type.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"LT"},{"children":[],"comments":"The 'equal to' ordering type.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"EQ"},{"children":[],"comments":"The 'greater than' ordering type.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"GT"}],"name":"Prim.Ordering","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Prim.Row/docs.json b/tests/purs/publish/basic-example/output/Prim.Row/docs.json new file mode 100644 index 000000000..081b2d363 --- /dev/null +++ b/tests/purs/publish/basic-example/output/Prim.Row/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Row module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains automatically solved type classes for working with row types.","declarations":[{"children":[],"comments":"The Union type class is used to compute the union of two rows of types\n(left-biased, including duplicates).\n\nThe third type argument represents the union of the first two.\n","info":{"arguments":[["left",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],["right",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],["union",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}]],"declType":"typeClass","fundeps":[[["left","right"],["union"]],[["right","union"],["left"]],[["union","left"],["right"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Union"},{"children":[],"comments":"The Nub type class is used to remove duplicate labels from rows.\n","info":{"arguments":[["original",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],["nubbed",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}]],"declType":"typeClass","fundeps":[[["original"],["nubbed"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Nub"},{"children":[],"comments":"The Lacks type class asserts that a label does not occur in a given row.\n","info":{"arguments":[["label",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["row",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Lacks"},{"children":[],"comments":"The Cons type class is a 4-way relation which asserts that one row of\ntypes can be obtained from another by inserting a new label/type pair on\nthe left.\n","info":{"arguments":[["label",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["a",{"annotation":[],"contents":"k","tag":"TypeVar"}],["tail",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],["row",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}]],"declType":"typeClass","fundeps":[[["label","a","tail"],["row"]],[["label","row"],["a","tail"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Cons"}],"name":"Prim.Row","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Prim.RowList/docs.json b/tests/purs/publish/basic-example/output/Prim.RowList/docs.json new file mode 100644 index 000000000..1ea89a442 --- /dev/null +++ b/tests/purs/publish/basic-example/output/Prim.RowList/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.RowList module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains a type level list (`RowList`) that represents an ordered view of a row of types.","declarations":[{"children":[],"comments":"A type level list representation of a row of types.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"RowList"},{"children":[],"comments":"Constructs a new `RowList` from a label, a type, and an existing tail\n`RowList`. E.g: `Cons \"x\" Int (Cons \"y\" Int Nil)`.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":{"identifier":"k","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim","RowList"],"RowList"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim","RowList"],"RowList"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Cons"},{"children":[],"comments":"The empty `RowList`.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":{"identifier":"k","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim","RowList"],"RowList"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Nil"},{"children":[],"comments":"Compiler solved type class for generating a `RowList` from a closed row\nof types. Entries are sorted by label and duplicates are preserved in\nthe order they appeared in the row.\n","info":{"arguments":[["row",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}],["list",{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim","RowList"],"RowList"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"}]],"declType":"typeClass","fundeps":[[["row"],["list"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"RowToList"}],"name":"Prim.RowList","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Prim.Symbol/docs.json b/tests/purs/publish/basic-example/output/Prim.Symbol/docs.json new file mode 100644 index 000000000..e2bc9ff2a --- /dev/null +++ b/tests/purs/publish/basic-example/output/Prim.Symbol/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.Symbol module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains automatically solved type classes for working with `Symbols`.","declarations":[{"children":[],"comments":"Compiler solved type class for appending `Symbol`s together.\n","info":{"arguments":[["left",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["right",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["appended",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["left","right"],["appended"]],[["right","appended"],["left"]],[["appended","left"],["right"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Append"},{"children":[],"comments":"Compiler solved type class for comparing two `Symbol`s.\nProduces an `Ordering`.\n","info":{"arguments":[["left",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["right",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["ordering",{"annotation":[],"contents":[["Prim","Ordering"],"Ordering"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["left","right"],["ordering"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Compare"},{"children":[],"comments":"Compiler solved type class for either splitting up a symbol into its\nhead and tail or for combining a head and tail into a new symbol.\nRequires the head to be a single character and the combined string\ncannot be empty.\n","info":{"arguments":[["head",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["tail",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],["symbol",{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[[["head","tail"],["symbol"]],[["symbol"],["head","tail"]]],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Cons"}],"name":"Prim.Symbol","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Prim.TypeError/docs.json b/tests/purs/publish/basic-example/output/Prim.TypeError/docs.json new file mode 100644 index 000000000..86ca13721 --- /dev/null +++ b/tests/purs/publish/basic-example/output/Prim.TypeError/docs.json @@ -0,0 +1 @@ +{"comments":"The Prim.TypeError module is embedded in the PureScript compiler. Unlike `Prim`, it is not imported implicitly. It contains type classes that provide custom type error and warning functionality.","declarations":[{"children":[],"comments":"The Warn type class allows a custom compiler warning to be displayed.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"arguments":[["message",{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Warn"},{"children":[],"comments":"The Fail type class is part of the custom type errors feature. To provide\na custom type error when someone tries to use a particular instance,\nwrite that instance out with a Fail constraint.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"arguments":[["message",{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}]],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Fail"},{"children":[],"comments":"`Doc` is the kind of type-level documents.\n\nThis kind is used with the `Fail` and `Warn` type classes.\nBuild up a `Doc` with `Text`, `Quote`, `QuoteLabel`, `Beside`, and `Above`.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Doc"},{"children":[],"comments":"The Text type constructor makes a Doc from a Symbol\nto be used in a custom type error.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Text"},{"children":[],"comments":"The Quote type constructor renders any concrete type as a Doc\nto be used in a custom type error.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":{"identifier":"k","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Quote"},{"children":[],"comments":"The `QuoteLabel` type constructor will produce a `Doc` when given a `Symbol`. When the resulting `Doc` is rendered\nfor a `Warn` or `Fail` constraint, a syntactically valid label will be produced, escaping with quotes as needed.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Symbol"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"QuoteLabel"},{"children":[],"comments":"The Beside type constructor combines two Docs horizontally\nto be used in a custom type error.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Beside"},{"children":[],"comments":"The Above type constructor combines two Docs vertically\nin a custom type error.\n\nFor more information, see\n[the Custom Type Errors guide](https://github.com/purescript/documentation/blob/master/guides/Custom-Type-Errors.md).\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim","TypeError"],"Doc"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Above"}],"name":"Prim.TypeError","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Prim/docs.json b/tests/purs/publish/basic-example/output/Prim/docs.json new file mode 100644 index 000000000..8a8ee9e8a --- /dev/null +++ b/tests/purs/publish/basic-example/output/Prim/docs.json @@ -0,0 +1 @@ +{"comments":"The `Prim` module is embedded in the PureScript compiler in order to provide compiler support for certain types — for example, value literals, or syntax sugar. It is implicitly imported unqualified in every module except those that list it as a qualified import.\n\n`Prim` does not include additional built-in types and kinds that are defined deeper in the compiler such as Type wildcards (e.g. `f :: _ -> Int`) and Quantified Types. Rather, these are documented in [the PureScript language reference](https://github.com/purescript/documentation/blob/master/language/Types.md).\n","declarations":[{"children":[],"comments":"A function, which takes values of the type specified by the first type\nparameter, and returns values of the type specified by the second.\nIn the JavaScript backend, this is a standard JavaScript Function.\n\nThe type constructor `(->)` is syntactic sugar for this type constructor.\nIt is recommended to use `(->)` rather than `Function`, where possible.\n\nThat is, prefer this:\n\n f :: Number -> Number\n\nto either of these:\n\n f :: Function Number Number\n f :: (->) Number Number\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Function"},{"children":[],"comments":"An Array: a data structure supporting efficient random access. In\nthe JavaScript backend, values of this type are represented as JavaScript\nArrays at runtime.\n\nConstruct values using literals:\n\n x = [1,2,3,4,5] :: Array Int\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Array"},{"children":[],"comments":"The type of records whose fields are known at compile time. In the\nJavaScript backend, values of this type are represented as JavaScript\nObjects at runtime.\n\nThe type signature here means that the `Record` type constructor takes\na row of concrete types. For example:\n\n type Person = Record (name :: String, age :: Number)\n\nThe syntactic sugar with curly braces `{ }` is generally preferred, though:\n\n type Person = { name :: String, age :: Number }\n\nThe row associates a type to each label which appears in the record.\n\n_Technical note_: PureScript allows duplicate labels in rows, and the\nmeaning of `Record r` is based on the _first_ occurrence of each label in\nthe row `r`.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Record"},{"children":[],"comments":"A double precision floating point number (IEEE 754).\n\nConstruct values of this type with literals.\nNegative literals must be wrapped in parentheses if the negation sign could be mistaken\nfor an infix operator:\n\n x = 35.23 :: Number\n y = -1.224e6 :: Number\n z = exp (-1.0) :: Number\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Number"},{"children":[],"comments":"A 32-bit signed integer. See the `purescript-integers` package for details\nof how this is accomplished when compiling to JavaScript.\n\nConstruct values of this type with literals. Hexadecimal syntax is supported.\nNegative literals must be wrapped in parentheses if the negation sign could be mistaken\nfor an infix operator:\n\n x = -23 :: Int\n y = 0x17 :: Int\n z = complement (-24) :: Int\n\nIntegers used as types are considered to have kind `Int`.\nUnlike value-level `Int`s, which must be representable as a 32-bit signed integer,\ntype-level `Int`s are unbounded. Hexadecimal support is also supported at the type level.\n\n type One :: Int\n type One = 1\n \n type Beyond32BitSignedInt :: Int\n type Beyond32BitSignedInt = 2147483648\n \n type HexInt :: Int\n type HexInt = 0x17\n\nNegative integer literals at the type level must be\nwrapped in parentheses if the negation sign could be mistaken for an infix operator.\n\n type NegativeOne = -1\n foo :: Proxy (-1) -> ...\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Int"},{"children":[],"comments":"A String. As in JavaScript, String values represent sequences of UTF-16\ncode units, which are not required to form a valid encoding of Unicode\ntext (for example, lone surrogates are permitted).\n\nConstruct values of this type with literals, using double quotes `\"`:\n\n x = \"hello, world\" :: String\n\nMulti-line string literals are also supported with triple quotes (`\"\"\"`):\n\n x = \"\"\"multi\n line\"\"\"\n\nAt the type level, string literals represent types with kind `Symbol`.\nThese types will have kind `String` in a future release:\n\n type Hello :: Symbol\n type Hello = \"Hello, world\"\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"String"},{"children":[],"comments":"A single character (UTF-16 code unit). The JavaScript representation is a\nnormal `String`, which is guaranteed to contain one code unit. This means\nthat astral plane characters (i.e. those with code point values greater\nthan `0xFFFF`) cannot be represented as `Char` values.\n\nConstruct values of this type with literals, using single quotes `'`:\n\n x = 'a' :: Char\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Char"},{"children":[],"comments":"A JavaScript Boolean value.\n\nConstruct values of this type with the literals `true` and `false`.\n\nThe `True` and `False` types defined in `Prim.Boolean` have this type as their kind.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Boolean"},{"children":[],"comments":"The Partial type class is used to indicate that a function is *partial,*\nthat is, it is not defined for all inputs. In practice, attempting to use\na partial function with a bad input will usually cause an error to be\nthrown, although it is not safe to assume that this will happen in all\ncases. For more information, see\n[purescript-partial](https://pursuit.purescript.org/packages/purescript-partial/).\n","info":{"arguments":[],"declType":"typeClass","fundeps":[],"superclasses":[]},"kind":null,"sourceSpan":null,"title":"Partial"},{"children":[],"comments":"`Type` is the kind of all proper types: those that classify value-level terms.\nFor example the type `Boolean` has kind `Type`; denoted by `Boolean :: Type`.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Type"},{"children":[],"comments":"`Constraint` is the kind of type class constraints.\nFor example, a type class declaration like this:\n\n class Semigroup a where\n append :: a -> a -> a\n\nhas the kind signature:\n\n class Semigroup :: Type -> Constraint\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Constraint"},{"children":[],"comments":"`Symbol` is the kind of type-level strings.\n\nConstruct types of this kind using the same literal syntax as documented\nfor strings.\n\n type Hello :: Symbol\n type Hello = \"Hello, world\"\n\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Symbol"},{"children":[],"comments":"`Row` is the kind constructor of label-indexed types which map type-level strings to other types.\nThe most common use of `Row` is `Row Type`, a row mapping labels to basic (of kind `Type`) types:\n\n type ExampleRow :: Row Type\n type ExampleRow = ( name :: String, values :: Array Int )\n\nThis is the kind of `Row` expected by the `Record` type constructor.\nMore advanced row kinds like `Row (Type -> Type)` are used much less frequently.\n","info":{"declType":"externData","kind":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"roles":[]},"kind":null,"sourceSpan":null,"title":"Row"}],"name":"Prim","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Record.Unsafe/docs.json b/tests/purs/publish/basic-example/output/Record.Unsafe/docs.json new file mode 100644 index 000000000..cf0f390d7 --- /dev/null +++ b/tests/purs/publish/basic-example/output/Record.Unsafe/docs.json @@ -0,0 +1 @@ +{"comments":"The functions in this module are highly unsafe as they treat records like\nstringly-keyed maps and can coerce the row of labels that a record has.\n\nThese function are intended for situations where there is some other way of\nproving things about the structure of the record - for example, when using\n`RowToList`. **They should never be used for general record manipulation.**\n","declarations":[{"children":[],"comments":"Checks if a record has a key, using a string for the key.\n","info":{"declType":"value","type":{"annotation":[],"contents":{"identifier":"r1","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[],"contents":"r1","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[10,70],"name":"../../../support/bower_components/purescript-prelude/src/Record/Unsafe.purs","start":[10,1]},"title":"unsafeHas"},{"children":[],"comments":"Unsafely gets a value from a record, using a string for the key.\n\nIf the key does not exist this will cause a runtime error elsewhere.\n","info":{"declType":"value","type":{"annotation":[],"contents":{"identifier":"r","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[15,64],"name":"../../../support/bower_components/purescript-prelude/src/Record/Unsafe.purs","start":[15,1]},"title":"unsafeGet"},{"children":[],"comments":"Unsafely sets a value on a record, using a string for the key.\n\nThe output record's row is unspecified so can be coerced to any row. If the\noutput type is incorrect it will cause a runtime error elsewhere.\n","info":{"declType":"value","type":{"annotation":[],"contents":{"identifier":"r1","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"r2","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[],"contents":"r1","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[],"contents":"r2","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[21,82],"name":"../../../support/bower_components/purescript-prelude/src/Record/Unsafe.purs","start":[21,1]},"title":"unsafeSet"},{"children":[],"comments":"Unsafely removes a value on a record, using a string for the key.\n\nThe output record's row is unspecified so can be coerced to any row. If the\noutput type is incorrect it will cause a runtime error elsewhere.\n","info":{"declType":"value","type":{"annotation":[],"contents":{"identifier":"r1","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"r2","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[],"contents":"r1","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[],"contents":"r2","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[27,78],"name":"../../../support/bower_components/purescript-prelude/src/Record/Unsafe.purs","start":[27,1]},"title":"unsafeDelete"}],"name":"Record.Unsafe","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Record.Unsafe/externs.cbor b/tests/purs/publish/basic-example/output/Record.Unsafe/externs.cbor new file mode 100644 index 000000000..aebd6a329 Binary files /dev/null and b/tests/purs/publish/basic-example/output/Record.Unsafe/externs.cbor differ diff --git a/tests/purs/publish/basic-example/output/Safe.Coerce/docs.json b/tests/purs/publish/basic-example/output/Safe.Coerce/docs.json new file mode 100644 index 000000000..7c20e9bca --- /dev/null +++ b/tests/purs/publish/basic-example/output/Safe.Coerce/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":"Coerce a value of one type to a value of some other type, without changing\nits runtime representation. This function behaves identically to\n`unsafeCoerce` at runtime. Unlike `unsafeCoerce`, it is safe, because the\n`Coercible` constraint prevents any use of this function from compiling\nunless the compiler can prove that the two types have the same runtime\nrepresentation.\n\nOne application for this function is to avoid doing work that you know is a\nno-op because of newtypes. For example, if you have an `Array (Conj a)` and you\nwant an `Array (Disj a)`, you could do `Data.Array.map (un Conj >>> Disj)`, but\nthis performs an unnecessary traversal of the array, with O(n) cost.\n`coerce` accomplishes the same with only O(1) cost:\n\n```purescript\nmapConjToDisj :: forall a. Array (Conj a) -> Array (Disj a)\nmapConjToDisj = coerce\n```\n","info":{"declType":"value","type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"b","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"constraintAnn":[],"constraintArgs":[{"annotation":[],"contents":"a","tag":"TypeVar"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"constraintClass":[["Prim","Coerce"],"Coercible"],"constraintData":null,"constraintKindArgs":[]},{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"ConstrainedType"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[26,46],"name":"../../../support/bower_components/purescript-safe-coerce/src/Safe/Coerce.purs","start":[26,1]},"title":"coerce"}],"name":"Safe.Coerce","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Safe.Coerce/externs.cbor b/tests/purs/publish/basic-example/output/Safe.Coerce/externs.cbor new file mode 100644 index 000000000..d6a4f9afc Binary files /dev/null and b/tests/purs/publish/basic-example/output/Safe.Coerce/externs.cbor differ diff --git a/tests/purs/publish/basic-example/output/Type.Proxy/docs.json b/tests/purs/publish/basic-example/output/Type.Proxy/docs.json new file mode 100644 index 000000000..72099694e --- /dev/null +++ b/tests/purs/publish/basic-example/output/Type.Proxy/docs.json @@ -0,0 +1 @@ +{"comments":"The `Proxy` type and values are for situations where type information is\nrequired for an input to determine the type of an output, but where it is\nnot possible or convenient to provide a _value_ for the input.\n\nA hypothetical example: if you have a class that is used to handle the\nresult of an AJAX request, you may want to use this information to set the\nexpected content type of the request, so you might have a class something\nlike this:\n\n``` purescript\nclass AjaxResponse a where\n responseType :: a -> ResponseType\n fromResponse :: Foreign -> a\n```\n\nThe problem here is `responseType` requires a value of type `a`, but we\nwon't have a value of that type until the request has been completed. The\nsolution is to use a `Proxy` type instead:\n\n``` purescript\nclass AjaxResponse a where\n responseType :: Proxy a -> ResponseType\n fromResponse :: Foreign -> a\n```\n\nWe can now call `responseType (Proxy :: Proxy SomeContentType)` to produce\na `ResponseType` for `SomeContentType` without having to construct some\nempty version of `SomeContentType` first. In situations like this where\nthe `Proxy` type can be statically determined, it is recommended to pull\nout the definition to the top level and make a declaration like:\n\n``` purescript\n_SomeContentType :: Proxy SomeContentType\n_SomeContentType = Proxy\n```\n\nThat way the proxy value can be used as `responseType _SomeContentType`\nfor improved readability. However, this is not always possible, sometimes\nthe type required will be determined by a type variable. As PureScript has\nscoped type variables, we can do things like this:\n\n``` purescript\nmakeRequest :: URL -> ResponseType -> Aff _ Foreign\nmakeRequest = ...\n\nfetchData :: forall a. (AjaxResponse a) => URL -> Aff _ a\nfetchData url = fromResponse <$> makeRequest url (responseType (Proxy :: Proxy a))\n```\n","declarations":[{"children":[{"comments":null,"info":{"arguments":[],"declType":"dataConstructor"},"sourceSpan":{"end":[53,21],"name":"../../../support/bower_components/purescript-prelude/src/Type/Proxy.purs","start":[53,14]},"title":"Proxy"}],"comments":"Proxy type for all `kind`s.\n","info":{"dataDeclType":"data","declType":"data","roles":["Phantom"],"typeArguments":[["a",null]]},"kind":{"keyword":"data","kind":{"annotation":[],"contents":{"identifier":"k","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"k","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"sourceSpan":{"end":[53,21],"name":"../../../support/bower_components/purescript-prelude/src/Type/Proxy.purs","start":[53,1]},"title":"Proxy"}],"name":"Type.Proxy","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Type.Proxy/externs.cbor b/tests/purs/publish/basic-example/output/Type.Proxy/externs.cbor new file mode 100644 index 000000000..c16541b99 Binary files /dev/null and b/tests/purs/publish/basic-example/output/Type.Proxy/externs.cbor differ diff --git a/tests/purs/publish/basic-example/output/Unsafe.Coerce/docs.json b/tests/purs/publish/basic-example/output/Unsafe.Coerce/docs.json new file mode 100644 index 000000000..efa181b46 --- /dev/null +++ b/tests/purs/publish/basic-example/output/Unsafe.Coerce/docs.json @@ -0,0 +1 @@ +{"comments":null,"declarations":[{"children":[],"comments":"A _highly unsafe_ function, which can be used to persuade the type system that\nany type is the same as any other type. When using this function, it is your\n(that is, the caller's) responsibility to ensure that the underlying\nrepresentation for both types is the same.\n\nBecause this function is extraordinarily flexible, type inference\ncan greatly suffer. It is highly recommended to define specializations of\nthis function rather than using it as-is. For example:\n\n```purescript\nfromBoolean :: Boolean -> Json\nfromBoolean = unsafeCoerce\n```\n\nThis way, you won't have any nasty surprises due to the inferred type being\ndifferent to what you expected.\n\nAfter the v0.14.0 PureScript release, some of what was accomplished via\n`unsafeCoerce` can now be accomplished via `coerce` from\n`purescript-safe-coerce`. See that library's documentation for more\ncontext.\n","info":{"declType":"value","type":{"annotation":[],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[],"contents":{"identifier":"b","kind":null,"skolem":null,"type":{"annotation":[],"contents":[{"annotation":[],"contents":[{"annotation":[],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"kind":null,"sourceSpan":{"end":[27,50],"name":"../../../support/bower_components/purescript-unsafe-coerce/src/Unsafe/Coerce.purs","start":[27,1]},"title":"unsafeCoerce"}],"name":"Unsafe.Coerce","reExports":[]} \ No newline at end of file diff --git a/tests/purs/publish/basic-example/output/Unsafe.Coerce/externs.cbor b/tests/purs/publish/basic-example/output/Unsafe.Coerce/externs.cbor new file mode 100644 index 000000000..78367c179 Binary files /dev/null and b/tests/purs/publish/basic-example/output/Unsafe.Coerce/externs.cbor differ diff --git a/tests/purs/publish/basic-example/output/package.json b/tests/purs/publish/basic-example/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purs/publish/basic-example/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/2018/A.purs b/tests/purus/passing/2018/A.purs new file mode 100644 index 000000000..bff4cd039 --- /dev/null +++ b/tests/purus/passing/2018/A.purs @@ -0,0 +1,7 @@ +module A where + +import B as Main + +-- Prior to the 2018 fix this would be detected as a cycle between A and Main. +foo ∷ Main.Foo → Main.Foo +foo x = x diff --git a/tests/purus/passing/2018/B.purs b/tests/purus/passing/2018/B.purs new file mode 100644 index 000000000..c87647d4c --- /dev/null +++ b/tests/purus/passing/2018/B.purs @@ -0,0 +1,3 @@ +module B where + +data Foo = X | Y diff --git a/tests/purus/passing/2018/output/A/externs.cbor b/tests/purus/passing/2018/output/A/externs.cbor new file mode 100644 index 000000000..2fee4fdd4 Binary files /dev/null and b/tests/purus/passing/2018/output/A/externs.cbor differ diff --git a/tests/purus/passing/2018/output/A/index.cfn b/tests/purus/passing/2018/output/A/index.cfn new file mode 100644 index 000000000..ebb4990f0 --- /dev/null +++ b/tests/purus/passing/2018/output/A/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,26],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,10],"start":[7,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[7,10],"start":[7,9]}},"kind":"Var","type":{"annotation":[{"end":[6,15],"name":"tests/purus/passing/2018/A.purs","start":[6,7]},[]],"contents":[["B"],"Foo"],"tag":"TypeConstructor"},"value":{"identifier":"x","sourcePos":[7,1]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/2018/A.purs","start":[6,7]},[]],"contents":[["B"],"Foo"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/2018/A.purs","start":[6,18]},[]],"contents":[["B"],"Foo"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"foo"}],"exports":["foo"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,17],"start":[3,1]}},"moduleName":["B"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,10],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["A"],"modulePath":"tests/purus/passing/2018/A.purs","reExports":{},"sourceSpan":{"end":[7,10],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/2018/output/A/index.cfn.pretty b/tests/purus/passing/2018/output/A/index.cfn.pretty new file mode 100644 index 000000000..9463be026 --- /dev/null +++ b/tests/purus/passing/2018/output/A/index.cfn.pretty @@ -0,0 +1,14 @@ +A (tests/purus/passing/2018/A.purs) +Imported Modules: + B, + Builtin, + Prim +Exports: + foo +Re-Exports: + +Foreign: + +Declarations: +foo :: Foo -> Foo +foo = \(x: Foo) -> (x: Foo) \ No newline at end of file diff --git a/tests/purus/passing/2018/output/B/externs.cbor b/tests/purus/passing/2018/output/B/externs.cbor new file mode 100644 index 000000000..529f82b73 Binary files /dev/null and b/tests/purus/passing/2018/output/B/externs.cbor differ diff --git a/tests/purus/passing/2018/output/B/index.cfn b/tests/purus/passing/2018/output/B/index.cfn new file mode 100644 index 000000000..5f77d504b --- /dev/null +++ b/tests/purus/passing/2018/output/B/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"Foo":["data",[],[{"dataCtorAnn":[{"end":[3,13],"name":"tests/purus/passing/2018/B.purs","start":[3,10]},[]],"dataCtorFields":[],"dataCtorName":"X"},{"dataCtorAnn":[{"end":[3,17],"name":"tests/purus/passing/2018/B.purs","start":[3,14]},[]],"dataCtorFields":[],"dataCtorName":"Y"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,17],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,17],"start":[3,1]}},"constructorName":"X","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["B"],"Foo"],"tag":"TypeConstructor"},"typeName":"Foo"},"identifier":"X"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,17],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,17],"start":[3,1]}},"constructorName":"Y","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["B"],"Foo"],"tag":"TypeConstructor"},"typeName":"Foo"},"identifier":"Y"}],"exports":["X","Y"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,17],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,17],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["B"],"modulePath":"tests/purus/passing/2018/B.purs","reExports":{},"sourceSpan":{"end":[3,17],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/2018/output/B/index.cfn.pretty b/tests/purus/passing/2018/output/B/index.cfn.pretty new file mode 100644 index 000000000..f3e6efc59 --- /dev/null +++ b/tests/purus/passing/2018/output/B/index.cfn.pretty @@ -0,0 +1,17 @@ +B (tests/purus/passing/2018/B.purs) +Imported Modules: + Builtin, + Prim +Exports: + X, + Y +Re-Exports: + +Foreign: + +Declarations: +X :: Foo +X = X + +Y :: Foo +Y = Y \ No newline at end of file diff --git a/tests/purus/passing/2018/output/package.json b/tests/purus/passing/2018/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/2018/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/2138/Lib.purs b/tests/purus/passing/2138/Lib.purs new file mode 100644 index 000000000..3c433e0b1 --- /dev/null +++ b/tests/purus/passing/2138/Lib.purs @@ -0,0 +1,3 @@ +module Lib (A(..), A) where + +data A = B | C diff --git a/tests/purus/passing/2138/output/Lib/externs.cbor b/tests/purus/passing/2138/output/Lib/externs.cbor new file mode 100644 index 000000000..c5437d9c9 Binary files /dev/null and b/tests/purus/passing/2138/output/Lib/externs.cbor differ diff --git a/tests/purus/passing/2138/output/Lib/index.cfn b/tests/purus/passing/2138/output/Lib/index.cfn new file mode 100644 index 000000000..5a181d55b --- /dev/null +++ b/tests/purus/passing/2138/output/Lib/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"A":["data",[],[{"dataCtorAnn":[{"end":[3,11],"name":"tests/purus/passing/2138/Lib.purs","start":[3,8]},[]],"dataCtorFields":[],"dataCtorName":"B"},{"dataCtorAnn":[{"end":[3,15],"name":"tests/purus/passing/2138/Lib.purs","start":[3,12]},[]],"dataCtorFields":[],"dataCtorName":"C"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"constructorName":"B","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"A"],"tag":"TypeConstructor"},"typeName":"A"},"identifier":"B"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"constructorName":"C","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"A"],"tag":"TypeConstructor"},"typeName":"A"},"identifier":"C"}],"exports":["B","C"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Lib"],"modulePath":"tests/purus/passing/2138/Lib.purs","reExports":{},"sourceSpan":{"end":[3,15],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/2138/output/Lib/index.cfn.pretty b/tests/purus/passing/2138/output/Lib/index.cfn.pretty new file mode 100644 index 000000000..38396b22f --- /dev/null +++ b/tests/purus/passing/2138/output/Lib/index.cfn.pretty @@ -0,0 +1,17 @@ +Lib (tests/purus/passing/2138/Lib.purs) +Imported Modules: + Builtin, + Prim +Exports: + B, + C +Re-Exports: + +Foreign: + +Declarations: +B :: A +B = B + +C :: A +C = C \ No newline at end of file diff --git a/tests/purus/passing/2138/output/package.json b/tests/purus/passing/2138/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/2138/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/2609/Eg.purs b/tests/purus/passing/2609/Eg.purs new file mode 100644 index 000000000..cd6e73d34 --- /dev/null +++ b/tests/purus/passing/2609/Eg.purs @@ -0,0 +1,5 @@ +module Eg (Foo'(Bar'), (:->)) where + +data Foo' = Bar' Int Int + +infix 4 Bar' as :-> diff --git a/tests/purus/passing/2609/output/Eg/externs.cbor b/tests/purus/passing/2609/output/Eg/externs.cbor new file mode 100644 index 000000000..b34925f9c Binary files /dev/null and b/tests/purus/passing/2609/output/Eg/externs.cbor differ diff --git a/tests/purus/passing/2609/output/Eg/index.cfn b/tests/purus/passing/2609/output/Eg/index.cfn new file mode 100644 index 000000000..b578d0afb --- /dev/null +++ b/tests/purus/passing/2609/output/Eg/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"Foo'":["data",[],[{"dataCtorAnn":[{"end":[3,17],"name":"tests/purus/passing/2609/Eg.purs","start":[3,11]},[]],"dataCtorFields":[[{"Ident":"value0"},{"annotation":[{"end":[3,21],"name":"tests/purus/passing/2609/Eg.purs","start":[3,18]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],[{"Ident":"value1"},{"annotation":[{"end":[3,25],"name":"tests/purus/passing/2609/Eg.purs","start":[3,22]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}]],"dataCtorName":"Bar'"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,25],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,25],"start":[3,1]}},"constructorName":"Bar'","fieldNames":["value0","value1"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,21],"name":"tests/purus/passing/2609/Eg.purs","start":[3,18]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,25],"name":"tests/purus/passing/2609/Eg.purs","start":[3,22]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Eg"],"Foo'"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"typeName":"Foo'"},"identifier":"Bar'"}],"exports":["Bar'"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,20],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,20],"start":[1,1]}},"moduleName":["Eg"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,20],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Eg"],"modulePath":"tests/purus/passing/2609/Eg.purs","reExports":{},"sourceSpan":{"end":[5,20],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/2609/output/Eg/index.cfn.pretty b/tests/purus/passing/2609/output/Eg/index.cfn.pretty new file mode 100644 index 000000000..e610aa7e0 --- /dev/null +++ b/tests/purus/passing/2609/output/Eg/index.cfn.pretty @@ -0,0 +1,14 @@ +Eg (tests/purus/passing/2609/Eg.purs) +Imported Modules: + Builtin, + Eg, + Prim +Exports: + Bar' +Re-Exports: + +Foreign: + +Declarations: +Bar' :: Int -> Int -> Foo' +Bar' = Bar' \ No newline at end of file diff --git a/tests/purus/passing/2609/output/package.json b/tests/purus/passing/2609/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/2609/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/4035/Other.purs b/tests/purus/passing/4035/Other.purs new file mode 100644 index 000000000..055b3c783 --- /dev/null +++ b/tests/purus/passing/4035/Other.purs @@ -0,0 +1,4 @@ +module Other where + +type Id :: forall k. k -> k +type Id a = a diff --git a/tests/purus/passing/4035/output/Other/externs.cbor b/tests/purus/passing/4035/output/Other/externs.cbor new file mode 100644 index 000000000..d0912d785 Binary files /dev/null and b/tests/purus/passing/4035/output/Other/externs.cbor differ diff --git a/tests/purus/passing/4035/output/Other/index.cfn b/tests/purus/passing/4035/output/Other/index.cfn new file mode 100644 index 000000000..2eff1f313 --- /dev/null +++ b/tests/purus/passing/4035/output/Other/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[],"exports":[],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,14],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,14],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Other"],"modulePath":"tests/purus/passing/4035/Other.purs","reExports":{},"sourceSpan":{"end":[4,14],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/4035/output/Other/index.cfn.pretty b/tests/purus/passing/4035/output/Other/index.cfn.pretty new file mode 100644 index 000000000..86bd3cdf3 --- /dev/null +++ b/tests/purus/passing/4035/output/Other/index.cfn.pretty @@ -0,0 +1,11 @@ +Other (tests/purus/passing/4035/Other.purs) +Imported Modules: + Builtin, + Prim +Exports: + +Re-Exports: + +Foreign: + +Declarations: diff --git a/tests/purus/passing/4035/output/package.json b/tests/purus/passing/4035/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/4035/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/4101/Lib.purs b/tests/purus/passing/4101/Lib.purs new file mode 100644 index 000000000..fc5f850e7 --- /dev/null +++ b/tests/purus/passing/4101/Lib.purs @@ -0,0 +1,9 @@ +module Lib where + +newtype Const :: forall k. Type -> k -> Type +newtype Const a b = Const a + +data Unit = Unit + +type CONST = Const +type UNIT = CONST Unit diff --git a/tests/purus/passing/4101/output/Lib/externs.cbor b/tests/purus/passing/4101/output/Lib/externs.cbor new file mode 100644 index 000000000..c026e2ce4 Binary files /dev/null and b/tests/purus/passing/4101/output/Lib/externs.cbor differ diff --git a/tests/purus/passing/4101/output/Lib/index.cfn b/tests/purus/passing/4101/output/Lib/index.cfn new file mode 100644 index 000000000..e8a14084e --- /dev/null +++ b/tests/purus/passing/4101/output/Lib/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"Const":["newtype",[["a",null],["b",null]],[{"dataCtorAnn":[{"end":[4,28],"name":"tests/purus/passing/4101/Lib.purs","start":[4,19]},[]],"dataCtorFields":[[{"Ident":"value0"},{"annotation":[{"end":[4,28],"name":"tests/purus/passing/4101/Lib.purs","start":[4,27]},[]],"contents":"a","tag":"TypeVar"}]],"dataCtorName":"Const"}]],"Unit":["data",[],[{"dataCtorAnn":[{"end":[6,17],"name":"tests/purus/passing/4101/Lib.purs","start":[6,11]},[]],"dataCtorFields":[],"dataCtorName":"Unit"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[6,1]}},"constructorName":"Unit","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Unit"],"tag":"TypeConstructor"},"typeName":"Unit"},"identifier":"Unit"},{"annotation":{"meta":null,"sourceSpan":{"end":[4,28],"start":[4,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[4,28],"start":[4,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[4,28],"start":[4,1]}},"kind":"Var","type":{"annotation":[{"end":[4,28],"name":"tests/purus/passing/4101/Lib.purs","start":[4,27]},[]],"contents":"a","tag":"TypeVar"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,28],"name":"tests/purus/passing/4101/Lib.purs","start":[4,27]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,28],"name":"tests/purus/passing/4101/Lib.purs","start":[4,27]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"Const"}],"exports":["Const","Unit"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[9,23],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,23],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Lib"],"modulePath":"tests/purus/passing/4101/Lib.purs","reExports":{},"sourceSpan":{"end":[9,23],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/4101/output/Lib/index.cfn.pretty b/tests/purus/passing/4101/output/Lib/index.cfn.pretty new file mode 100644 index 000000000..e0001ad97 --- /dev/null +++ b/tests/purus/passing/4101/output/Lib/index.cfn.pretty @@ -0,0 +1,17 @@ +Lib (tests/purus/passing/4101/Lib.purs) +Imported Modules: + Builtin, + Prim +Exports: + Const, + Unit +Re-Exports: + +Foreign: + +Declarations: +Unit :: Unit +Unit = Unit + +Const :: forall a. a -> a +Const = \(x: a) -> (x: a) \ No newline at end of file diff --git a/tests/purus/passing/4101/output/package.json b/tests/purus/passing/4101/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/4101/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/4105/Lib.purs b/tests/purus/passing/4105/Lib.purs new file mode 100644 index 000000000..89ccc3043 --- /dev/null +++ b/tests/purus/passing/4105/Lib.purs @@ -0,0 +1,5 @@ +module Lib where + +type Template col = { bio :: col String } +type Identity a = a +type Patch = Template Identity diff --git a/tests/purus/passing/4105/output/Lib/externs.cbor b/tests/purus/passing/4105/output/Lib/externs.cbor new file mode 100644 index 000000000..cfb270a36 Binary files /dev/null and b/tests/purus/passing/4105/output/Lib/externs.cbor differ diff --git a/tests/purus/passing/4105/output/Lib/index.cfn b/tests/purus/passing/4105/output/Lib/index.cfn new file mode 100644 index 000000000..b17f80203 --- /dev/null +++ b/tests/purus/passing/4105/output/Lib/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[],"exports":[],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,31],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,31],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Lib"],"modulePath":"tests/purus/passing/4105/Lib.purs","reExports":{},"sourceSpan":{"end":[5,31],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/4105/output/Lib/index.cfn.pretty b/tests/purus/passing/4105/output/Lib/index.cfn.pretty new file mode 100644 index 000000000..4cafcdc60 --- /dev/null +++ b/tests/purus/passing/4105/output/Lib/index.cfn.pretty @@ -0,0 +1,11 @@ +Lib (tests/purus/passing/4105/Lib.purs) +Imported Modules: + Builtin, + Prim +Exports: + +Re-Exports: + +Foreign: + +Declarations: diff --git a/tests/purus/passing/4105/output/package.json b/tests/purus/passing/4105/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/4105/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/4200/Lib.purs b/tests/purus/passing/4200/Lib.purs new file mode 100644 index 000000000..645940a23 --- /dev/null +++ b/tests/purus/passing/4200/Lib.purs @@ -0,0 +1,7 @@ +module Lib where + +data T :: forall m. m -> Type +data T msg = E + +type TAlias :: forall k. k -> Type +type TAlias msg = T msg diff --git a/tests/purus/passing/4200/output/Lib/externs.cbor b/tests/purus/passing/4200/output/Lib/externs.cbor new file mode 100644 index 000000000..d0ee9d943 Binary files /dev/null and b/tests/purus/passing/4200/output/Lib/externs.cbor differ diff --git a/tests/purus/passing/4200/output/Lib/index.cfn b/tests/purus/passing/4200/output/Lib/index.cfn new file mode 100644 index 000000000..ee1a0ebe2 --- /dev/null +++ b/tests/purus/passing/4200/output/Lib/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"T":["data",[["msg",null]],[{"dataCtorAnn":[{"end":[4,15],"name":"tests/purus/passing/4200/Lib.purs","start":[4,12]},[]],"dataCtorFields":[],"dataCtorName":"E"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[4,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[4,1]}},"constructorName":"E","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[3,30],"name":"tests/purus/passing/4200/Lib.purs","start":[3,11]},[]],"contents":{"identifier":"m","kind":{"annotation":[{"end":[3,25],"name":"tests/purus/passing/4200/Lib.purs","start":[3,23]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"msg","kind":{"annotation":[{"end":[3,22],"name":"tests/purus/passing/4200/Lib.purs","start":[3,21]},[]],"contents":"m","tag":"TypeVar"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"T"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"m","tag":"TypeVar"}],"tag":"KindApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"msg","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"typeName":"T"},"identifier":"E"}],"exports":["E"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[7,24],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,24],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Lib"],"modulePath":"tests/purus/passing/4200/Lib.purs","reExports":{},"sourceSpan":{"end":[7,24],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/4200/output/Lib/index.cfn.pretty b/tests/purus/passing/4200/output/Lib/index.cfn.pretty new file mode 100644 index 000000000..c428541be --- /dev/null +++ b/tests/purus/passing/4200/output/Lib/index.cfn.pretty @@ -0,0 +1,13 @@ +Lib (tests/purus/passing/4200/Lib.purs) +Imported Modules: + Builtin, + Prim +Exports: + E +Re-Exports: + +Foreign: + +Declarations: +E :: forall (m :: Type) (@msg :: m). T@m msg +E = E \ No newline at end of file diff --git a/tests/purus/passing/4200/output/package.json b/tests/purus/passing/4200/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/4200/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/4310/Lib.purs b/tests/purus/passing/4310/Lib.purs new file mode 100644 index 000000000..2c5b87070 --- /dev/null +++ b/tests/purus/passing/4310/Lib.purs @@ -0,0 +1,20 @@ +module Lib where + +data Tuple a b = Tuple a b + +infixr 6 Tuple as /\ +infixr 6 type Tuple as /\ + +mappend :: String -> String -> String +mappend _ _ = "mappend" + +infixr 5 mappend as <> + +class Test a where + runTest :: a -> String + +instance Test Int where + runTest _ = "4" + +instance (Test a, Test b) => Test (a /\ b) where + runTest (a /\ b) = runTest a <> runTest b diff --git a/tests/purus/passing/4310/output/Lib/externs.cbor b/tests/purus/passing/4310/output/Lib/externs.cbor new file mode 100644 index 000000000..0c4ee2c6e Binary files /dev/null and b/tests/purus/passing/4310/output/Lib/externs.cbor differ diff --git a/tests/purus/passing/4310/output/Lib/index.cfn b/tests/purus/passing/4310/output/Lib/index.cfn new file mode 100644 index 000000000..a4b511219 --- /dev/null +++ b/tests/purus/passing/4310/output/Lib/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"Test$Dict":["newtype",[["a",null]],[{"dataCtorAnn":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[13,1]},[]],"dataCtorFields":[[{"Ident":"dict"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["runTest",{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[14,15],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}]],"dataCtorName":"Test$Dict"}]],"Tuple":["data",[["a",null],["b",null]],[{"dataCtorAnn":[{"end":[3,23],"name":"tests/purus/passing/4310/Lib.purs","start":[3,16]},[]],"dataCtorFields":[[{"Ident":"value0"},{"annotation":[{"end":[3,25],"name":"tests/purus/passing/4310/Lib.purs","start":[3,24]},[]],"contents":"a","tag":"TypeVar"}],[{"Ident":"value1"},{"annotation":[{"end":[3,27],"name":"tests/purus/passing/4310/Lib.purs","start":[3,26]},[]],"contents":"b","tag":"TypeVar"}]],"dataCtorName":"Tuple"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,27],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,27],"start":[3,1]}},"constructorName":"Tuple","fieldNames":["value0","value1"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"b","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,25],"name":"tests/purus/passing/4310/Lib.purs","start":[3,24]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,27],"name":"tests/purus/passing/4310/Lib.purs","start":[3,26]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Tuple"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"typeName":"Tuple"},"identifier":"Tuple"},{"annotation":{"meta":{"metaType":"IsTypeClassConstructor"},"sourceSpan":{"end":[14,25],"start":[13,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[14,25],"start":[13,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[14,25],"start":[13,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["runTest",{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[14,15],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["runTest",{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[14,15],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["runTest",{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[14,15],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"Test$Dict"},{"annotation":{"meta":null,"sourceSpan":{"end":[17,18],"start":[16,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[17,18],"start":[16,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["runTest",{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[16,18],"name":"tests/purus/passing/4310/Lib.purs","start":[16,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[16,18],"name":"tests/purus/passing/4310/Lib.purs","start":[16,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"Test$Dict","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[17,18],"start":[16,1]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[17,18],"start":[16,1]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["runTest",{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[16,18],"name":"tests/purus/passing/4310/Lib.purs","start":[16,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[["runTest",{"annotation":{"meta":null,"sourceSpan":{"end":[17,18],"start":[17,3]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[17,18],"start":[17,15]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"4"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[16,18],"name":"tests/purus/passing/4310/Lib.purs","start":[16,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}}]]}},"kind":"App"},"identifier":"testInt"},{"annotation":{"meta":null,"sourceSpan":{"end":[14,25],"start":[14,3]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[14,25],"start":[14,3]}},"argument":"dict","body":{"annotation":{"meta":null,"sourceSpan":{"end":[14,25],"start":[14,3]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[14,25],"start":[14,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[14,25],"start":[14,3]}},"binderType":"VarBinder","identifier":"v"}],"constructorName":{"identifier":"Test$Dict","moduleName":["Lib"]},"typeName":{"identifier":"Test$Dict","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[14,25],"start":[14,3]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[14,25],"start":[14,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["runTest",{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"v","sourcePos":[14,3]}},"fieldName":"runTest","kind":"Accessor","type":{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[14,15],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[14,25],"start":[14,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"dict","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[14,15],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":1,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[14,15],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"}},"identifier":"runTest"},{"annotation":{"meta":null,"sourceSpan":{"end":[8,38],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[9,24],"start":[9,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[9,24],"start":[9,1]}},"argument":"v1","body":{"annotation":{"meta":null,"sourceSpan":{"end":[9,24],"start":[9,15]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"mappend"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,28],"name":"tests/purus/passing/4310/Lib.purs","start":[8,22]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,38],"name":"tests/purus/passing/4310/Lib.purs","start":[8,32]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,18],"name":"tests/purus/passing/4310/Lib.purs","start":[8,12]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,38],"name":"tests/purus/passing/4310/Lib.purs","start":[8,22]},[]],"contents":[{"annotation":[{"end":[8,38],"name":"tests/purus/passing/4310/Lib.purs","start":[8,22]},[]],"contents":[{"annotation":[{"end":[8,31],"name":"tests/purus/passing/4310/Lib.purs","start":[8,29]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,28],"name":"tests/purus/passing/4310/Lib.purs","start":[8,22]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,38],"name":"tests/purus/passing/4310/Lib.purs","start":[8,32]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"mappend"},{"annotation":{"meta":null,"sourceSpan":{"end":[20,44],"start":[19,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"dictTest","body":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"dictTest1","body":{"abstraction":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[20,44],"start":[19,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["runTest",{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[20,44],"name":"tests/purus/passing/4310/Lib.purs","start":[19,1]},[]],"contents":[["Lib"],"Tuple"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,37],"name":"tests/purus/passing/4310/Lib.purs","start":[19,36]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[19,42],"name":"tests/purus/passing/4310/Lib.purs","start":[19,41]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[20,44],"name":"tests/purus/passing/4310/Lib.purs","start":[19,1]},[]],"contents":[["Lib"],"Tuple"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,37],"name":"tests/purus/passing/4310/Lib.purs","start":[19,36]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[19,42],"name":"tests/purus/passing/4310/Lib.purs","start":[19,41]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"Test$Dict","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["runTest",{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[20,44],"name":"tests/purus/passing/4310/Lib.purs","start":[19,1]},[]],"contents":[["Lib"],"Tuple"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,37],"name":"tests/purus/passing/4310/Lib.purs","start":[19,36]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[19,42],"name":"tests/purus/passing/4310/Lib.purs","start":[19,41]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[["runTest",{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"constructorType":"ProductType","identifiers":["value0","value1"],"metaType":"IsConstructor"},"sourceSpan":{"end":[20,16],"start":[20,14]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[20,13],"start":[20,12]}},"binderType":"VarBinder","identifier":"a"},{"annotation":{"meta":null,"sourceSpan":{"end":[20,18],"start":[20,17]}},"binderType":"VarBinder","identifier":"b"}],"constructorName":{"identifier":"Tuple","moduleName":["Lib"]},"typeName":{"identifier":"Tuple","moduleName":["Lib"]}}],"expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[20,34],"start":[20,32]}},"kind":"Var","type":{"annotation":[{"end":[8,38],"name":"tests/purus/passing/4310/Lib.purs","start":[8,12]},[]],"contents":[{"annotation":[{"end":[8,38],"name":"tests/purus/passing/4310/Lib.purs","start":[8,12]},[]],"contents":[{"annotation":[{"end":[8,21],"name":"tests/purus/passing/4310/Lib.purs","start":[8,19]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,18],"name":"tests/purus/passing/4310/Lib.purs","start":[8,12]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,38],"name":"tests/purus/passing/4310/Lib.purs","start":[8,22]},[]],"contents":[{"annotation":[{"end":[8,38],"name":"tests/purus/passing/4310/Lib.purs","start":[8,22]},[]],"contents":[{"annotation":[{"end":[8,31],"name":"tests/purus/passing/4310/Lib.purs","start":[8,29]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,28],"name":"tests/purus/passing/4310/Lib.purs","start":[8,22]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,38],"name":"tests/purus/passing/4310/Lib.purs","start":[8,32]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"mappend","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[20,44],"start":[20,22]}},"argument":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[20,29],"start":[20,22]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":1,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[14,15],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"runTest","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[20,31],"start":[20,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,17],"name":"tests/purus/passing/4310/Lib.purs","start":[19,16]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"dictTest","sourcePos":[0,0]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[20,31],"start":[20,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[20,31],"start":[20,30]}},"kind":"Var","type":{"annotation":[{"end":[19,37],"name":"tests/purus/passing/4310/Lib.purs","start":[19,36]},[]],"contents":"a","tag":"TypeVar"},"value":{"identifier":"a","sourcePos":[20,12]}},"kind":"App"},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[20,44],"start":[20,22]}},"argument":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[20,42],"start":[20,35]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":1,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":[{"annotation":[{"end":[14,18],"name":"tests/purus/passing/4310/Lib.purs","start":[14,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[14,15],"name":"tests/purus/passing/4310/Lib.purs","start":[14,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"runTest","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[20,44],"start":[20,35]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,25],"name":"tests/purus/passing/4310/Lib.purs","start":[19,24]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"dictTest1","sourcePos":[0,0]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[20,44],"start":[20,35]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[20,44],"start":[20,43]}},"kind":"Var","type":{"annotation":[{"end":[19,42],"name":"tests/purus/passing/4310/Lib.purs","start":[19,41]},[]],"contents":"b","tag":"TypeVar"},"value":{"identifier":"b","sourcePos":[20,17]}},"kind":"App"},"kind":"App"},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[20,44],"start":[20,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[20,44],"name":"tests/purus/passing/4310/Lib.purs","start":[19,1]},[]],"contents":[["Lib"],"Tuple"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,37],"name":"tests/purus/passing/4310/Lib.purs","start":[19,36]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[19,42],"name":"tests/purus/passing/4310/Lib.purs","start":[19,41]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"v","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[20,44],"name":"tests/purus/passing/4310/Lib.purs","start":[19,1]},[]],"contents":[["Lib"],"Tuple"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,37],"name":"tests/purus/passing/4310/Lib.purs","start":[19,36]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[19,42],"name":"tests/purus/passing/4310/Lib.purs","start":[19,41]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[14,25],"name":"tests/purus/passing/4310/Lib.purs","start":[14,19]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}}]]}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,25],"name":"tests/purus/passing/4310/Lib.purs","start":[19,24]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[20,44],"name":"tests/purus/passing/4310/Lib.purs","start":[19,1]},[]],"contents":[["Lib"],"Tuple"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,37],"name":"tests/purus/passing/4310/Lib.purs","start":[19,36]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[19,42],"name":"tests/purus/passing/4310/Lib.purs","start":[19,41]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[19,17],"name":"tests/purus/passing/4310/Lib.purs","start":[19,11]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":3,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"b","kind":{"annotation":[{"end":[19,25],"name":"tests/purus/passing/4310/Lib.purs","start":[19,19]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":2,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,17],"name":"tests/purus/passing/4310/Lib.purs","start":[19,16]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,25],"name":"tests/purus/passing/4310/Lib.purs","start":[19,24]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Test$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[20,44],"name":"tests/purus/passing/4310/Lib.purs","start":[19,1]},[]],"contents":[["Lib"],"Tuple"],"tag":"TypeConstructor"},{"annotation":[{"end":[19,37],"name":"tests/purus/passing/4310/Lib.purs","start":[19,36]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[19,42],"name":"tests/purus/passing/4310/Lib.purs","start":[19,41]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"test/\\"}],"exports":["runTest","Tuple","mappend","testInt","test/\\"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[20,44],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[20,44],"start":[1,1]}},"moduleName":["Lib"]},{"annotation":{"meta":null,"sourceSpan":{"end":[20,44],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Lib"],"modulePath":"tests/purus/passing/4310/Lib.purs","reExports":{},"sourceSpan":{"end":[20,44],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/4310/output/Lib/index.cfn.pretty b/tests/purus/passing/4310/output/Lib/index.cfn.pretty new file mode 100644 index 000000000..d807163ae --- /dev/null +++ b/tests/purus/passing/4310/output/Lib/index.cfn.pretty @@ -0,0 +1,54 @@ +Lib (tests/purus/passing/4310/Lib.purs) +Imported Modules: + Builtin, + Lib, + Prim +Exports: + runTest, + Tuple, + mappend, + testInt, + test/\ +Re-Exports: + +Foreign: + +Declarations: +Tuple :: forall (@a :: Type) (@b :: Type). a -> b -> (Tuple a b) +Tuple = Tuple + +Test$Dict :: forall a. { runTest :: a -> String } -> { runTest :: a -> String } +Test$Dict = \(x: { runTest :: a -> String }) -> (x: { runTest :: a -> String }) + +testInt :: Test$Dict Int +testInt = + (Test$Dict: { runTest :: Int -> String } -> Test$Dict Int) + ({ runTest: \(v: Int) -> ("4": String) }: { runTest :: Int -> String }) + +runTest :: forall (@a :: Type). Test$Dict a -> a -> String +runTest = + \(dict: Test$Dict a) -> + case (dict: Test$Dict a) of + Test$Dict v -> (v: { runTest :: a -> String }).runTest + +mappend :: String -> String -> String +mappend = \(v: String) -> \(v1: String) -> ("mappend": String) + +test/\ :: forall (a :: Type) (b :: Type). Test$Dict a -> Test$Dict b -> Test$Dict (Tuple a b) +test/\ = + \(dictTest: Test$Dict a) -> + \(dictTest1: Test$Dict b) -> + (Test$Dict: { runTest :: (Tuple a b) -> String } -> + Test$Dict (Tuple a b)) + ({ + runTest: \(v: (Tuple a b)) -> + case (v: (Tuple a b)) of + Tuple a b -> + (mappend: String -> String -> String) + ((runTest: forall (@a :: Type). Test$Dict a -> a -> String) + (dictTest: Test$Dict a) + (a: a)) + ((runTest: forall (@a :: Type). Test$Dict a -> a -> String) + (dictTest1: Test$Dict b) + (b: b)) + }: { runTest :: (Tuple a b) -> String }) \ No newline at end of file diff --git a/tests/purus/passing/4310/output/package.json b/tests/purus/passing/4310/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/4310/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ClassRefSyntax/Lib.purs b/tests/purus/passing/ClassRefSyntax/Lib.purs new file mode 100644 index 000000000..c9eca67a7 --- /dev/null +++ b/tests/purus/passing/ClassRefSyntax/Lib.purs @@ -0,0 +1,5 @@ +module Lib (class X, go) where + +class X a where + go :: a -> a + diff --git a/tests/purus/passing/ClassRefSyntax/output/Lib/externs.cbor b/tests/purus/passing/ClassRefSyntax/output/Lib/externs.cbor new file mode 100644 index 000000000..bcd1359dd Binary files /dev/null and b/tests/purus/passing/ClassRefSyntax/output/Lib/externs.cbor differ diff --git a/tests/purus/passing/ClassRefSyntax/output/Lib/index.cfn b/tests/purus/passing/ClassRefSyntax/output/Lib/index.cfn new file mode 100644 index 000000000..3b51f011a --- /dev/null +++ b/tests/purus/passing/ClassRefSyntax/output/Lib/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"X$Dict":["newtype",[["a",null]],[{"dataCtorAnn":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[3,1]},[]],"dataCtorFields":[[{"Ident":"dict"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["go",{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,13],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,10],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}]],"dataCtorName":"X$Dict"}]]},"decls":[{"annotation":{"meta":{"metaType":"IsTypeClassConstructor"},"sourceSpan":{"end":[4,15],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[4,15],"start":[3,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[3,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["go",{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,13],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,10],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["go",{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,13],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,10],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["go",{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,13],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,10],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"X$Dict"},{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[4,3]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[4,3]}},"argument":"dict","body":{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[4,3]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[4,15],"start":[4,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[4,3]}},"binderType":"VarBinder","identifier":"v"}],"constructorName":{"identifier":"X$Dict","moduleName":["Lib"]},"typeName":{"identifier":"X$Dict","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[4,3]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[4,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["go",{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,13],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[4,13],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,11]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"v","sourcePos":[4,3]}},"fieldName":"go","kind":"Accessor","type":{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,13],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,10],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[4,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"X$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"dict","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,13],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,10],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":0,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"X$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":[{"annotation":[{"end":[4,13],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,10],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,15],"name":"tests/purus/passing/ClassRefSyntax/Lib.purs","start":[4,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"}},"identifier":"go"}],"exports":["go"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[1,1]}},"moduleName":["Lib"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Lib"],"modulePath":"tests/purus/passing/ClassRefSyntax/Lib.purs","reExports":{},"sourceSpan":{"end":[4,15],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ClassRefSyntax/output/Lib/index.cfn.pretty b/tests/purus/passing/ClassRefSyntax/output/Lib/index.cfn.pretty new file mode 100644 index 000000000..d3c4dc809 --- /dev/null +++ b/tests/purus/passing/ClassRefSyntax/output/Lib/index.cfn.pretty @@ -0,0 +1,20 @@ +Lib (tests/purus/passing/ClassRefSyntax/Lib.purs) +Imported Modules: + Builtin, + Lib, + Prim +Exports: + go +Re-Exports: + +Foreign: + +Declarations: +X$Dict :: forall a. { go :: a -> a } -> { go :: a -> a } +X$Dict = \(x: { go :: a -> a }) -> (x: { go :: a -> a }) + +go :: forall (@a :: Type). X$Dict a -> a -> a +go = + \(dict: X$Dict a) -> + case (dict: X$Dict a) of + X$Dict v -> (v: { go :: a -> a }).go \ No newline at end of file diff --git a/tests/purus/passing/ClassRefSyntax/output/package.json b/tests/purus/passing/ClassRefSyntax/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ClassRefSyntax/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/Coercible/Lib.purs b/tests/purus/passing/Coercible/Lib.purs new file mode 100644 index 000000000..cca268cfb --- /dev/null +++ b/tests/purus/passing/Coercible/Lib.purs @@ -0,0 +1,12 @@ +module Coercible.Lib + ( module Coercible.Lib2 + , NTLib1 (..) + , NTLib3 (..) + ) where + +import Coercible.Lib2 + +newtype NTLib1 a = NTLib1 a + +newtype NTLib3 a b = NTLib3 a +type role NTLib3 representational representational diff --git a/tests/purus/passing/Coercible/Lib2.purs b/tests/purus/passing/Coercible/Lib2.purs new file mode 100644 index 000000000..3fdef618d --- /dev/null +++ b/tests/purus/passing/Coercible/Lib2.purs @@ -0,0 +1,3 @@ +module Coercible.Lib2 where + +newtype NTLib2 a = NTLib2 a diff --git a/tests/purus/passing/Coercible/output/Coercible.Lib/externs.cbor b/tests/purus/passing/Coercible/output/Coercible.Lib/externs.cbor new file mode 100644 index 000000000..dd75611f3 Binary files /dev/null and b/tests/purus/passing/Coercible/output/Coercible.Lib/externs.cbor differ diff --git a/tests/purus/passing/Coercible/output/Coercible.Lib/index.cfn b/tests/purus/passing/Coercible/output/Coercible.Lib/index.cfn new file mode 100644 index 000000000..9b3e64770 --- /dev/null +++ b/tests/purus/passing/Coercible/output/Coercible.Lib/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"NTLib1":["newtype",[["a",null]],[{"dataCtorAnn":[{"end":[9,28],"name":"tests/purus/passing/Coercible/Lib.purs","start":[9,18]},[]],"dataCtorFields":[[{"Ident":"value0"},{"annotation":[{"end":[9,28],"name":"tests/purus/passing/Coercible/Lib.purs","start":[9,27]},[]],"contents":"a","tag":"TypeVar"}]],"dataCtorName":"NTLib1"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[11,30],"start":[11,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[11,30],"start":[11,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[11,30],"start":[11,1]}},"kind":"Var","type":{"annotation":[{"end":[11,30],"name":"tests/purus/passing/Coercible/Lib.purs","start":[11,29]},[]],"contents":"a","tag":"TypeVar"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,30],"name":"tests/purus/passing/Coercible/Lib.purs","start":[11,29]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[11,30],"name":"tests/purus/passing/Coercible/Lib.purs","start":[11,29]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"NTLib3"},{"annotation":{"meta":null,"sourceSpan":{"end":[9,28],"start":[9,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[9,28],"start":[9,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[9,28],"start":[9,1]}},"kind":"Var","type":{"annotation":[{"end":[9,28],"name":"tests/purus/passing/Coercible/Lib.purs","start":[9,27]},[]],"contents":"a","tag":"TypeVar"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[9,28],"name":"tests/purus/passing/Coercible/Lib.purs","start":[9,27]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[9,28],"name":"tests/purus/passing/Coercible/Lib.purs","start":[9,27]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"NTLib1"}],"exports":["NTLib1","NTLib3"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[12,51],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,22],"start":[7,1]}},"moduleName":["Coercible","Lib2"]},{"annotation":{"meta":null,"sourceSpan":{"end":[12,51],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Coercible","Lib"],"modulePath":"tests/purus/passing/Coercible/Lib.purs","reExports":{"Coercible.Lib2":["NTLib2"]},"sourceSpan":{"end":[12,51],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/Coercible/output/Coercible.Lib/index.cfn.pretty b/tests/purus/passing/Coercible/output/Coercible.Lib/index.cfn.pretty new file mode 100644 index 000000000..4337bdc29 --- /dev/null +++ b/tests/purus/passing/Coercible/output/Coercible.Lib/index.cfn.pretty @@ -0,0 +1,18 @@ +Coercible.Lib (tests/purus/passing/Coercible/Lib.purs) +Imported Modules: + Builtin, + Coercible.Lib2, + Prim +Exports: + NTLib1, + NTLib3 +Re-Exports: + Coercible.Lib2.NTLib2 +Foreign: + +Declarations: +NTLib3 :: forall a. a -> a +NTLib3 = \(x: a) -> (x: a) + +NTLib1 :: forall a. a -> a +NTLib1 = \(x: a) -> (x: a) \ No newline at end of file diff --git a/tests/purus/passing/Coercible/output/Coercible.Lib2/externs.cbor b/tests/purus/passing/Coercible/output/Coercible.Lib2/externs.cbor new file mode 100644 index 000000000..959ccddcb Binary files /dev/null and b/tests/purus/passing/Coercible/output/Coercible.Lib2/externs.cbor differ diff --git a/tests/purus/passing/Coercible/output/Coercible.Lib2/index.cfn b/tests/purus/passing/Coercible/output/Coercible.Lib2/index.cfn new file mode 100644 index 000000000..f0a8e978d --- /dev/null +++ b/tests/purus/passing/Coercible/output/Coercible.Lib2/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"NTLib2":["newtype",[["a",null]],[{"dataCtorAnn":[{"end":[3,28],"name":"tests/purus/passing/Coercible/Lib2.purs","start":[3,18]},[]],"dataCtorFields":[[{"Ident":"value0"},{"annotation":[{"end":[3,28],"name":"tests/purus/passing/Coercible/Lib2.purs","start":[3,27]},[]],"contents":"a","tag":"TypeVar"}]],"dataCtorName":"NTLib2"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,28],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[3,28],"start":[3,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[3,28],"start":[3,1]}},"kind":"Var","type":{"annotation":[{"end":[3,28],"name":"tests/purus/passing/Coercible/Lib2.purs","start":[3,27]},[]],"contents":"a","tag":"TypeVar"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,28],"name":"tests/purus/passing/Coercible/Lib2.purs","start":[3,27]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[3,28],"name":"tests/purus/passing/Coercible/Lib2.purs","start":[3,27]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"NTLib2"}],"exports":["NTLib2"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,28],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,28],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Coercible","Lib2"],"modulePath":"tests/purus/passing/Coercible/Lib2.purs","reExports":{},"sourceSpan":{"end":[3,28],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/Coercible/output/Coercible.Lib2/index.cfn.pretty b/tests/purus/passing/Coercible/output/Coercible.Lib2/index.cfn.pretty new file mode 100644 index 000000000..669656a21 --- /dev/null +++ b/tests/purus/passing/Coercible/output/Coercible.Lib2/index.cfn.pretty @@ -0,0 +1,13 @@ +Coercible.Lib2 (tests/purus/passing/Coercible/Lib2.purs) +Imported Modules: + Builtin, + Prim +Exports: + NTLib2 +Re-Exports: + +Foreign: + +Declarations: +NTLib2 :: forall a. a -> a +NTLib2 = \(x: a) -> (x: a) \ No newline at end of file diff --git a/tests/purus/passing/Coercible/output/package.json b/tests/purus/passing/Coercible/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/Coercible/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/DctorOperatorAlias/List.purs b/tests/purus/passing/DctorOperatorAlias/List.purs new file mode 100644 index 000000000..a428343a2 --- /dev/null +++ b/tests/purus/passing/DctorOperatorAlias/List.purs @@ -0,0 +1,5 @@ +module List where + +data List a = Cons a (List a) | Nil + +infixr 6 Cons as : diff --git a/tests/purus/passing/DctorOperatorAlias/output/List/externs.cbor b/tests/purus/passing/DctorOperatorAlias/output/List/externs.cbor new file mode 100644 index 000000000..e8d88fd04 Binary files /dev/null and b/tests/purus/passing/DctorOperatorAlias/output/List/externs.cbor differ diff --git a/tests/purus/passing/DctorOperatorAlias/output/List/index.cfn b/tests/purus/passing/DctorOperatorAlias/output/List/index.cfn new file mode 100644 index 000000000..719c997cf --- /dev/null +++ b/tests/purus/passing/DctorOperatorAlias/output/List/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,36],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,36],"start":[3,1]}},"constructorName":"Cons","fieldNames":["value0","value1"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,21],"name":"tests/purus/passing/DctorOperatorAlias/List.purs","start":[3,20]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,29],"name":"tests/purus/passing/DctorOperatorAlias/List.purs","start":[3,23]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["List"],"List"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,29],"name":"tests/purus/passing/DctorOperatorAlias/List.purs","start":[3,28]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["List"],"List"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"typeName":"List"},"identifier":"Cons"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,36],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,36],"start":[3,1]}},"constructorName":"Nil","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["List"],"List"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"typeName":"List"},"identifier":"Nil"}],"exports":["Cons","Nil"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,19],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,19],"start":[1,1]}},"moduleName":["List"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,19],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["List"],"modulePath":"tests/purus/passing/DctorOperatorAlias/List.purs","reExports":{},"sourceSpan":{"end":[5,19],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/DctorOperatorAlias/output/List/index.cfn.pretty b/tests/purus/passing/DctorOperatorAlias/output/List/index.cfn.pretty new file mode 100644 index 000000000..68d83e1b9 --- /dev/null +++ b/tests/purus/passing/DctorOperatorAlias/output/List/index.cfn.pretty @@ -0,0 +1,18 @@ +List (tests/purus/passing/DctorOperatorAlias/List.purs) +Imported Modules: + Builtin, + List, + Prim +Exports: + Cons, + Nil +Re-Exports: + +Foreign: + +Declarations: +Cons :: forall (@a :: Type). a -> List a -> List a +Cons = Cons + +Nil :: forall (@a :: Type). List a +Nil = Nil \ No newline at end of file diff --git a/tests/purus/passing/DctorOperatorAlias/output/package.json b/tests/purus/passing/DctorOperatorAlias/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/DctorOperatorAlias/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ExplicitImportReExport/Bar.purs b/tests/purus/passing/ExplicitImportReExport/Bar.purs new file mode 100644 index 000000000..5f8ef12ae --- /dev/null +++ b/tests/purus/passing/ExplicitImportReExport/Bar.purs @@ -0,0 +1,3 @@ +module Bar (module Foo) where + +import Foo diff --git a/tests/purus/passing/ExplicitImportReExport/Foo.purs b/tests/purus/passing/ExplicitImportReExport/Foo.purs new file mode 100644 index 000000000..d2c06e960 --- /dev/null +++ b/tests/purus/passing/ExplicitImportReExport/Foo.purs @@ -0,0 +1,4 @@ +module Foo where + +foo :: Int +foo = 3 diff --git a/tests/purus/passing/ExplicitImportReExport/output/Bar/externs.cbor b/tests/purus/passing/ExplicitImportReExport/output/Bar/externs.cbor new file mode 100644 index 000000000..9c12f3dd2 Binary files /dev/null and b/tests/purus/passing/ExplicitImportReExport/output/Bar/externs.cbor differ diff --git a/tests/purus/passing/ExplicitImportReExport/output/Bar/index.cfn b/tests/purus/passing/ExplicitImportReExport/output/Bar/index.cfn new file mode 100644 index 000000000..cf69bf063 --- /dev/null +++ b/tests/purus/passing/ExplicitImportReExport/output/Bar/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[],"exports":[],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,11],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,11],"start":[3,1]}},"moduleName":["Foo"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,11],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Bar"],"modulePath":"tests/purus/passing/ExplicitImportReExport/Bar.purs","reExports":{"Foo":["foo"]},"sourceSpan":{"end":[3,11],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ExplicitImportReExport/output/Bar/index.cfn.pretty b/tests/purus/passing/ExplicitImportReExport/output/Bar/index.cfn.pretty new file mode 100644 index 000000000..a6ff4d1a2 --- /dev/null +++ b/tests/purus/passing/ExplicitImportReExport/output/Bar/index.cfn.pretty @@ -0,0 +1,12 @@ +Bar (tests/purus/passing/ExplicitImportReExport/Bar.purs) +Imported Modules: + Builtin, + Foo, + Prim +Exports: + +Re-Exports: + Foo.foo +Foreign: + +Declarations: diff --git a/tests/purus/passing/ExplicitImportReExport/output/Foo/externs.cbor b/tests/purus/passing/ExplicitImportReExport/output/Foo/externs.cbor new file mode 100644 index 000000000..82a0a00f0 Binary files /dev/null and b/tests/purus/passing/ExplicitImportReExport/output/Foo/externs.cbor differ diff --git a/tests/purus/passing/ExplicitImportReExport/output/Foo/index.cfn b/tests/purus/passing/ExplicitImportReExport/output/Foo/index.cfn new file mode 100644 index 000000000..48f701f78 --- /dev/null +++ b/tests/purus/passing/ExplicitImportReExport/output/Foo/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,11],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,8],"start":[4,7]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":3}},"identifier":"foo"}],"exports":["foo"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,8],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,8],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Foo"],"modulePath":"tests/purus/passing/ExplicitImportReExport/Foo.purs","reExports":{},"sourceSpan":{"end":[4,8],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ExplicitImportReExport/output/Foo/index.cfn.pretty b/tests/purus/passing/ExplicitImportReExport/output/Foo/index.cfn.pretty new file mode 100644 index 000000000..130659647 --- /dev/null +++ b/tests/purus/passing/ExplicitImportReExport/output/Foo/index.cfn.pretty @@ -0,0 +1,13 @@ +Foo (tests/purus/passing/ExplicitImportReExport/Foo.purs) +Imported Modules: + Builtin, + Prim +Exports: + foo +Re-Exports: + +Foreign: + +Declarations: +foo :: Int +foo = (3: Int) \ No newline at end of file diff --git a/tests/purus/passing/ExplicitImportReExport/output/package.json b/tests/purus/passing/ExplicitImportReExport/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ExplicitImportReExport/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ExportExplicit/M1.purs b/tests/purus/passing/ExportExplicit/M1.purs new file mode 100644 index 000000000..5195d0e96 --- /dev/null +++ b/tests/purus/passing/ExportExplicit/M1.purs @@ -0,0 +1,10 @@ +module M1 (X(X, Y), Z(..), foo) where + +data X = X | Y +data Z = Z + +foo :: Int +foo = 0 + +bar :: Int +bar = 1 diff --git a/tests/purus/passing/ExportExplicit/output/M1/externs.cbor b/tests/purus/passing/ExportExplicit/output/M1/externs.cbor new file mode 100644 index 000000000..d9611677b Binary files /dev/null and b/tests/purus/passing/ExportExplicit/output/M1/externs.cbor differ diff --git a/tests/purus/passing/ExportExplicit/output/M1/index.cfn b/tests/purus/passing/ExportExplicit/output/M1/index.cfn new file mode 100644 index 000000000..c1f4168b3 --- /dev/null +++ b/tests/purus/passing/ExportExplicit/output/M1/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"X":["data",[],[{"dataCtorAnn":[{"end":[3,11],"name":"tests/purus/passing/ExportExplicit/M1.purs","start":[3,8]},[]],"dataCtorFields":[],"dataCtorName":"X"},{"dataCtorAnn":[{"end":[3,15],"name":"tests/purus/passing/ExportExplicit/M1.purs","start":[3,12]},[]],"dataCtorFields":[],"dataCtorName":"Y"}]],"Z":["data",[],[{"dataCtorAnn":[{"end":[4,11],"name":"tests/purus/passing/ExportExplicit/M1.purs","start":[4,8]},[]],"dataCtorFields":[],"dataCtorName":"Z"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,11],"start":[4,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,11],"start":[4,1]}},"constructorName":"Z","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["M1"],"Z"],"tag":"TypeConstructor"},"typeName":"Z"},"identifier":"Z"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"constructorName":"X","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["M1"],"X"],"tag":"TypeConstructor"},"typeName":"X"},"identifier":"X"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"constructorName":"Y","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["M1"],"X"],"tag":"TypeConstructor"},"typeName":"X"},"identifier":"Y"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,11],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,8],"start":[7,7]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":0}},"identifier":"foo"},{"annotation":{"meta":null,"sourceSpan":{"end":[9,11],"start":[9,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[10,8],"start":[10,7]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"identifier":"bar"}],"exports":["X","Y","Z","foo"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[10,8],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[10,8],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M1"],"modulePath":"tests/purus/passing/ExportExplicit/M1.purs","reExports":{},"sourceSpan":{"end":[10,8],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ExportExplicit/output/M1/index.cfn.pretty b/tests/purus/passing/ExportExplicit/output/M1/index.cfn.pretty new file mode 100644 index 000000000..a3ab16bed --- /dev/null +++ b/tests/purus/passing/ExportExplicit/output/M1/index.cfn.pretty @@ -0,0 +1,28 @@ +M1 (tests/purus/passing/ExportExplicit/M1.purs) +Imported Modules: + Builtin, + Prim +Exports: + X, + Y, + Z, + foo +Re-Exports: + +Foreign: + +Declarations: +Z :: Z +Z = Z + +X :: X +X = X + +Y :: X +Y = Y + +foo :: Int +foo = (0: Int) + +bar :: Int +bar = (1: Int) \ No newline at end of file diff --git a/tests/purus/passing/ExportExplicit/output/package.json b/tests/purus/passing/ExportExplicit/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ExportExplicit/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ExportExplicit2/M1.purs b/tests/purus/passing/ExportExplicit2/M1.purs new file mode 100644 index 000000000..aa78149f1 --- /dev/null +++ b/tests/purus/passing/ExportExplicit2/M1.purs @@ -0,0 +1,7 @@ +module M1 (bar) where + +foo :: Int +foo = 0 + +bar :: Int +bar = foo diff --git a/tests/purus/passing/ExportExplicit2/output/M1/externs.cbor b/tests/purus/passing/ExportExplicit2/output/M1/externs.cbor new file mode 100644 index 000000000..b665d9a86 Binary files /dev/null and b/tests/purus/passing/ExportExplicit2/output/M1/externs.cbor differ diff --git a/tests/purus/passing/ExportExplicit2/output/M1/index.cfn b/tests/purus/passing/ExportExplicit2/output/M1/index.cfn new file mode 100644 index 000000000..b512cc7d9 --- /dev/null +++ b/tests/purus/passing/ExportExplicit2/output/M1/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,11],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,8],"start":[4,7]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":0}},"identifier":"foo"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,11],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,10],"start":[7,7]}},"kind":"Var","type":{"annotation":[{"end":[3,11],"name":"tests/purus/passing/ExportExplicit2/M1.purs","start":[3,8]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"foo","moduleName":["M1"]}},"identifier":"bar"}],"exports":["bar"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[7,10],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,10],"start":[1,1]}},"moduleName":["M1"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M1"],"modulePath":"tests/purus/passing/ExportExplicit2/M1.purs","reExports":{},"sourceSpan":{"end":[7,10],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ExportExplicit2/output/M1/index.cfn.pretty b/tests/purus/passing/ExportExplicit2/output/M1/index.cfn.pretty new file mode 100644 index 000000000..583f99c2c --- /dev/null +++ b/tests/purus/passing/ExportExplicit2/output/M1/index.cfn.pretty @@ -0,0 +1,17 @@ +M1 (tests/purus/passing/ExportExplicit2/M1.purs) +Imported Modules: + Builtin, + M1, + Prim +Exports: + bar +Re-Exports: + +Foreign: + +Declarations: +foo :: Int +foo = (0: Int) + +bar :: Int +bar = (foo: Int) \ No newline at end of file diff --git a/tests/purus/passing/ExportExplicit2/output/package.json b/tests/purus/passing/ExportExplicit2/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ExportExplicit2/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ForeignKind/Lib.purs b/tests/purus/passing/ForeignKind/Lib.purs new file mode 100644 index 000000000..d28a9a5cc --- /dev/null +++ b/tests/purus/passing/ForeignKind/Lib.purs @@ -0,0 +1,60 @@ +module ForeignKinds.Lib (Nat, Kinded, Zero, Succ, N0, N1, N2, N3, NatProxy(..), class AddNat, addNat, proxy1, proxy2) where + +-- declaration + +data Nat + +-- use in foreign data + +foreign import data Zero :: Nat +foreign import data Succ :: Nat -> Nat + +-- use in data + +data NatProxy (t :: Nat) = NatProxy + +-- use in type sig + +succProxy :: forall n. NatProxy n -> NatProxy (Succ n) +succProxy _ = NatProxy + +-- use in alias + +type Kinded f = f :: Nat + +type KindedZero = Kinded Zero + +type N0 = Zero +type N1 = Succ N0 +type N2 = Succ N1 +type N3 = Succ N2 + +-- use of alias + +proxy0 :: NatProxy N0 +proxy0 = NatProxy + +proxy1 :: NatProxy N1 +proxy1 = NatProxy + +proxy2 :: NatProxy N2 +proxy2 = NatProxy + +proxy3 :: NatProxy N3 +proxy3 = NatProxy + +-- use in class + +class AddNat (l :: Nat) (r :: Nat) (o :: Nat) | l -> r o + +instance addNatZero + :: AddNat Zero r r + +instance addNatSucc + :: AddNat l r o + => AddNat (Succ l) r (Succ o) + +-- use of class + +addNat :: forall l r o. AddNat l r o => NatProxy l -> NatProxy r -> NatProxy o +addNat _ _ = NatProxy diff --git a/tests/purus/passing/ForeignKind/output/ForeignKinds.Lib/externs.cbor b/tests/purus/passing/ForeignKind/output/ForeignKinds.Lib/externs.cbor new file mode 100644 index 000000000..9b4509b67 Binary files /dev/null and b/tests/purus/passing/ForeignKind/output/ForeignKinds.Lib/externs.cbor differ diff --git a/tests/purus/passing/ForeignKind/output/ForeignKinds.Lib/index.cfn b/tests/purus/passing/ForeignKind/output/ForeignKinds.Lib/index.cfn new file mode 100644 index 000000000..d6dd9fb46 --- /dev/null +++ b/tests/purus/passing/ForeignKind/output/ForeignKinds.Lib/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"AddNat$Dict":["newtype",[["l",{"annotation":[{"end":[48,23],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[48,20]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"}],["r",{"annotation":[{"end":[48,34],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[48,31]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"}],["o",{"annotation":[{"end":[48,45],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[48,42]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"}]],[{"dataCtorAnn":[{"end":[48,57],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[48,1]},[{"LineComment":" use in class"}]],"dataCtorFields":[[{"Ident":"dict"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}]],"dataCtorName":"AddNat$Dict"}]],"Nat":["data",[],[]],"NatProxy":["data",[["t",{"annotation":[{"end":[14,24],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[14,21]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"}]],[{"dataCtorAnn":[{"end":[14,36],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[14,26]},[]],"dataCtorFields":[],"dataCtorName":"NatProxy"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[14,36],"start":[14,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[14,36],"start":[14,1]}},"constructorName":"NatProxy","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"t","kind":{"annotation":[{"end":[14,24],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[14,21]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"t","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"typeName":"NatProxy"},"identifier":"NatProxy"},{"annotation":{"meta":{"metaType":"IsTypeClassConstructor"},"sourceSpan":{"end":[48,57],"start":[48,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[48,57],"start":[48,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[48,57],"start":[48,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"AddNat$Dict"},{"annotation":{"meta":null,"sourceSpan":{"end":[18,55],"start":[18,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[19,23],"start":[19,1]}},"argument":"v","body":{"annotation":{"meta":{"constructorType":"ProductType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[19,23],"start":[19,15]}},"kind":"Var","type":{"annotation":[{"end":[18,55],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,38]},[]],"contents":[{"annotation":[{"end":[18,46],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,38]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[18,54],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,48]},[]],"contents":[{"annotation":[{"end":[18,52],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,48]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[18,54],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,53]},[]],"contents":"n","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"NatProxy","moduleName":["ForeignKinds","Lib"]}},"kind":"Abs","type":{"annotation":[{"end":[18,55],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,14]},[]],"contents":{"identifier":"n","kind":{"annotation":[{"end":[18,32],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,24]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"},"skolem":0,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[18,34],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,24]},[]],"contents":[{"annotation":[{"end":[18,32],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,24]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[18,34],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,33]},[]],"contents":"n","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[18,55],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,38]},[]],"contents":[{"annotation":[{"end":[18,46],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,38]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[18,54],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,48]},[]],"contents":[{"annotation":[{"end":[18,52],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,48]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[18,54],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[18,53]},[]],"contents":"n","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"succProxy"},{"annotation":{"meta":null,"sourceSpan":{"end":[43,22],"start":[43,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"constructorType":"ProductType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[44,18],"start":[44,10]}},"kind":"Var","type":{"annotation":[{"end":[43,22],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[43,11]},[]],"contents":[{"annotation":[{"end":[43,19],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[43,11]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[30,11]},[]],"contents":[{"annotation":[{"end":[30,15],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[30,11]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[29,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[29,11]},[]],"contents":[{"annotation":[{"end":[29,15],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[29,11]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[28,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[28,11]},[]],"contents":[{"annotation":[{"end":[28,15],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[28,11]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[27,15],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[27,11]},[]],"contents":[["ForeignKinds","Lib"],"Zero"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"NatProxy","moduleName":["ForeignKinds","Lib"]}},"identifier":"proxy3"},{"annotation":{"meta":null,"sourceSpan":{"end":[40,22],"start":[40,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"constructorType":"ProductType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[41,18],"start":[41,10]}},"kind":"Var","type":{"annotation":[{"end":[40,22],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[40,11]},[]],"contents":[{"annotation":[{"end":[40,19],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[40,11]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[29,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[29,11]},[]],"contents":[{"annotation":[{"end":[29,15],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[29,11]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[28,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[28,11]},[]],"contents":[{"annotation":[{"end":[28,15],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[28,11]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[27,15],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[27,11]},[]],"contents":[["ForeignKinds","Lib"],"Zero"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"NatProxy","moduleName":["ForeignKinds","Lib"]}},"identifier":"proxy2"},{"annotation":{"meta":null,"sourceSpan":{"end":[37,22],"start":[37,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"constructorType":"ProductType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[38,18],"start":[38,10]}},"kind":"Var","type":{"annotation":[{"end":[37,22],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[37,11]},[]],"contents":[{"annotation":[{"end":[37,19],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[37,11]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[28,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[28,11]},[]],"contents":[{"annotation":[{"end":[28,15],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[28,11]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[27,15],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[27,11]},[]],"contents":[["ForeignKinds","Lib"],"Zero"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"NatProxy","moduleName":["ForeignKinds","Lib"]}},"identifier":"proxy1"},{"annotation":{"meta":null,"sourceSpan":{"end":[34,22],"start":[34,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"constructorType":"ProductType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[35,18],"start":[35,10]}},"kind":"Var","type":{"annotation":[{"end":[34,22],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[34,11]},[]],"contents":[{"annotation":[{"end":[34,19],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[34,11]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[27,15],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[27,11]},[]],"contents":[["ForeignKinds","Lib"],"Zero"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"NatProxy","moduleName":["ForeignKinds","Lib"]}},"identifier":"proxy0"},{"annotation":{"meta":null,"sourceSpan":{"end":[51,21],"start":[50,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[51,21],"start":[50,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["ForeignKinds","Lib"],"AddNat$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[51,17],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[51,13]},[]],"contents":[["ForeignKinds","Lib"],"Zero"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[51,19],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[51,18]},[]],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[51,19],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[51,18]},[]],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"AddNat$Dict","moduleName":["ForeignKinds","Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[51,21],"start":[50,1]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[51,21],"start":[50,1]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[]}},"kind":"App"},"identifier":"addNatZero"},{"annotation":{"meta":null,"sourceSpan":{"end":[55,32],"start":[53,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"$__unused","body":{"abstraction":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[55,32],"start":[53,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["ForeignKinds","Lib"],"AddNat$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[55,20],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,14]},[]],"contents":[{"annotation":[{"end":[55,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,14]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[55,20],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,19]},[]],"contents":"l","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[55,23],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,22]},[]],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[55,31],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,25]},[]],"contents":[{"annotation":[{"end":[55,29],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,25]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[55,31],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,30]},[]],"contents":"o","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"AddNat$Dict","moduleName":["ForeignKinds","Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[]}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"l","kind":{"annotation":[{"end":[54,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[54,6]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"},"skolem":14,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"r","kind":{"annotation":[{"end":[54,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[54,6]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"},"skolem":13,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"o","kind":{"annotation":[{"end":[54,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[54,6]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"},"skolem":12,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["ForeignKinds","Lib"],"AddNat$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[54,14],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[54,13]},[]],"contents":"l","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[54,16],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[54,15]},[]],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[54,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[54,17]},[]],"contents":"o","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["ForeignKinds","Lib"],"AddNat$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[55,20],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,14]},[]],"contents":[{"annotation":[{"end":[55,18],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,14]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[55,20],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,19]},[]],"contents":"l","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[55,23],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,22]},[]],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[55,31],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,25]},[]],"contents":[{"annotation":[{"end":[55,29],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,25]},[]],"contents":[["ForeignKinds","Lib"],"Succ"],"tag":"TypeConstructor"},{"annotation":[{"end":[55,31],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[55,30]},[]],"contents":"o","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"addNatSucc"},{"annotation":{"meta":null,"sourceSpan":{"end":[59,79],"start":[59,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"$__unused","body":{"annotation":{"meta":null,"sourceSpan":{"end":[60,22],"start":[60,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[60,22],"start":[60,1]}},"argument":"v1","body":{"annotation":{"meta":{"constructorType":"ProductType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[60,22],"start":[60,14]}},"kind":"Var","type":{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,69]},[]],"contents":[{"annotation":[{"end":[59,77],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,69]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,78]},[]],"contents":"o","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"NatProxy","moduleName":["ForeignKinds","Lib"]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,65],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,55]},[]],"contents":[{"annotation":[{"end":[59,63],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,55]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,65],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,64]},[]],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,69]},[]],"contents":[{"annotation":[{"end":[59,77],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,69]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,78]},[]],"contents":"o","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,51],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,41]},[]],"contents":[{"annotation":[{"end":[59,49],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,41]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,51],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,50]},[]],"contents":"l","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,55]},[]],"contents":[{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,55]},[]],"contents":[{"annotation":[{"end":[59,68],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,66]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,65],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,55]},[]],"contents":[{"annotation":[{"end":[59,63],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,55]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,65],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,64]},[]],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,69]},[]],"contents":[{"annotation":[{"end":[59,77],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,69]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,78]},[]],"contents":"o","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,11]},[]],"contents":{"identifier":"l","kind":{"annotation":[{"end":[59,37],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,25]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"},"skolem":23,"type":{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,20]},[]],"contents":{"identifier":"r","kind":{"annotation":[{"end":[59,37],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,25]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"},"skolem":22,"type":{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,22]},[]],"contents":{"identifier":"o","kind":{"annotation":[{"end":[59,37],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,25]},[]],"contents":[["ForeignKinds","Lib"],"Nat"],"tag":"TypeConstructor"},"skolem":21,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["ForeignKinds","Lib"],"AddNat$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,33],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,32]},[]],"contents":"l","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[59,35],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,34]},[]],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[59,37],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,36]},[]],"contents":"o","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,41]},[]],"contents":[{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,41]},[]],"contents":[{"annotation":[{"end":[59,54],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,52]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,51],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,41]},[]],"contents":[{"annotation":[{"end":[59,49],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,41]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,51],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,50]},[]],"contents":"l","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,55]},[]],"contents":[{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,55]},[]],"contents":[{"annotation":[{"end":[59,68],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,66]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,65],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,55]},[]],"contents":[{"annotation":[{"end":[59,63],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,55]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,65],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,64]},[]],"contents":"r","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,69]},[]],"contents":[{"annotation":[{"end":[59,77],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,69]},[]],"contents":[["ForeignKinds","Lib"],"NatProxy"],"tag":"TypeConstructor"},{"annotation":[{"end":[59,79],"name":"tests/purus/passing/ForeignKind/Lib.purs","start":[59,78]},[]],"contents":"o","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"addNat"}],"exports":["NatProxy","addNat","proxy1","proxy2","addNatZero","addNatSucc"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[60,22],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[60,22],"start":[1,1]}},"moduleName":["ForeignKinds","Lib"]},{"annotation":{"meta":null,"sourceSpan":{"end":[60,22],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["ForeignKinds","Lib"],"modulePath":"tests/purus/passing/ForeignKind/Lib.purs","reExports":{},"sourceSpan":{"end":[60,22],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ForeignKind/output/ForeignKinds.Lib/index.cfn.pretty b/tests/purus/passing/ForeignKind/output/ForeignKinds.Lib/index.cfn.pretty new file mode 100644 index 000000000..a864242b8 --- /dev/null +++ b/tests/purus/passing/ForeignKind/output/ForeignKinds.Lib/index.cfn.pretty @@ -0,0 +1,55 @@ +ForeignKinds.Lib (tests/purus/passing/ForeignKind/Lib.purs) +Imported Modules: + Builtin, + ForeignKinds.Lib, + Prim +Exports: + NatProxy, + addNat, + proxy1, + proxy2, + addNatZero, + addNatSucc +Re-Exports: + +Foreign: + +Declarations: +NatProxy :: forall (@t :: Nat). NatProxy t +NatProxy = NatProxy + +AddNat$Dict :: Record {} -> Record {} +AddNat$Dict = \(x: Record {}) -> (x: Record {}) + +succProxy :: forall (n :: Nat). NatProxy n -> NatProxy Succ n +succProxy = \(v: NatProxy n) -> (NatProxy: NatProxy Succ n) + +proxy3 :: NatProxy Succ Succ Succ Zero +proxy3 = (NatProxy: NatProxy Succ Succ Succ Zero) + +proxy2 :: NatProxy Succ Succ Zero +proxy2 = (NatProxy: NatProxy Succ Succ Zero) + +proxy1 :: NatProxy Succ Zero +proxy1 = (NatProxy: NatProxy Succ Zero) + +proxy0 :: NatProxy Zero +proxy0 = (NatProxy: NatProxy Zero) + +addNatZero :: ((AddNat$Dict Zero r) r) +addNatZero = + (AddNat$Dict: Record {}@Type -> ((AddNat$Dict Zero r) r)) + ({ }: Record {}@Type) + +addNatSucc :: forall (l :: Nat) (r :: Nat) (o :: Nat). ((AddNat$Dict l r) o) -> ((AddNat$Dict Succ l r) Succ o) +addNatSucc = + \($__unused: ((AddNat$Dict l r) o)) -> + (AddNat$Dict: Record {}@Type -> ((AddNat$Dict Succ l r) Succ o)) + ({ }: Record {}@Type) + +addNat :: forall (l :: Nat) (r :: Nat) (o :: Nat). ((AddNat$Dict l r) o) -> NatProxy l -> NatProxy r -> NatProxy o +addNat = + \($__unused: ((AddNat$Dict l r) o)) -> + \(v: NatProxy l) -> + \(v1: NatProxy r) -> + (NatProxy: NatProxy o) \ No newline at end of file diff --git a/tests/purus/passing/ForeignKind/output/package.json b/tests/purus/passing/ForeignKind/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ForeignKind/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/Import/M1.purs b/tests/purus/passing/Import/M1.purs new file mode 100644 index 000000000..ec5358550 --- /dev/null +++ b/tests/purus/passing/Import/M1.purs @@ -0,0 +1,6 @@ +module M1 where + +id :: forall a. a -> a +id = \x -> x + +foo = id diff --git a/tests/purus/passing/Import/M2.purs b/tests/purus/passing/Import/M2.purs new file mode 100644 index 000000000..a6a9846e7 --- /dev/null +++ b/tests/purus/passing/Import/M2.purs @@ -0,0 +1,5 @@ +module M2 where + +import M1 + +main = \_ -> foo 42 diff --git a/tests/purus/passing/Import/output/M1/externs.cbor b/tests/purus/passing/Import/output/M1/externs.cbor new file mode 100644 index 000000000..d45eb454a Binary files /dev/null and b/tests/purus/passing/Import/output/M1/externs.cbor differ diff --git a/tests/purus/passing/Import/output/M1/index.cfn b/tests/purus/passing/Import/output/M1/index.cfn new file mode 100644 index 000000000..8d2e3a33e --- /dev/null +++ b/tests/purus/passing/Import/output/M1/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,23],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,8],"start":[4,7]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[4,13],"start":[4,12]}},"kind":"Var","type":{"annotation":[{"end":[3,18],"name":"tests/purus/passing/Import/M1.purs","start":[3,17]},[]],"contents":"a","tag":"TypeVar"},"value":{"identifier":"x","sourcePos":[4,7]}},"kind":"Abs","type":{"annotation":[{"end":[3,23],"name":"tests/purus/passing/Import/M1.purs","start":[3,7]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[3,21],"name":"tests/purus/passing/Import/M1.purs","start":[3,19]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":0,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,18],"name":"tests/purus/passing/Import/M1.purs","start":[3,17]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[3,23],"name":"tests/purus/passing/Import/M1.purs","start":[3,22]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"id"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,9],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,9],"start":[6,7]}},"kind":"Var","type":{"annotation":[{"end":[3,23],"name":"tests/purus/passing/Import/M1.purs","start":[3,7]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[3,21],"name":"tests/purus/passing/Import/M1.purs","start":[3,19]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":0,"type":{"annotation":[{"end":[3,23],"name":"tests/purus/passing/Import/M1.purs","start":[3,17]},[]],"contents":[{"annotation":[{"end":[3,23],"name":"tests/purus/passing/Import/M1.purs","start":[3,17]},[]],"contents":[{"annotation":[{"end":[3,21],"name":"tests/purus/passing/Import/M1.purs","start":[3,19]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,18],"name":"tests/purus/passing/Import/M1.purs","start":[3,17]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[3,23],"name":"tests/purus/passing/Import/M1.purs","start":[3,22]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"id","moduleName":["M1"]}},"identifier":"foo"}],"exports":["id","foo"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,9],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,9],"start":[1,1]}},"moduleName":["M1"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,9],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M1"],"modulePath":"tests/purus/passing/Import/M1.purs","reExports":{},"sourceSpan":{"end":[6,9],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/Import/output/M1/index.cfn.pretty b/tests/purus/passing/Import/output/M1/index.cfn.pretty new file mode 100644 index 000000000..e05de109c --- /dev/null +++ b/tests/purus/passing/Import/output/M1/index.cfn.pretty @@ -0,0 +1,18 @@ +M1 (tests/purus/passing/Import/M1.purs) +Imported Modules: + Builtin, + M1, + Prim +Exports: + id, + foo +Re-Exports: + +Foreign: + +Declarations: +id :: forall (a :: Type). a -> a +id = \(x: a) -> (x: a) + +foo :: forall (a :: Type). a -> a +foo = (id: forall (a :: Type). a -> a) \ No newline at end of file diff --git a/tests/purus/passing/Import/output/M2/externs.cbor b/tests/purus/passing/Import/output/M2/externs.cbor new file mode 100644 index 000000000..bbb97f95a Binary files /dev/null and b/tests/purus/passing/Import/output/M2/externs.cbor differ diff --git a/tests/purus/passing/Import/output/M2/index.cfn b/tests/purus/passing/Import/output/M2/index.cfn new file mode 100644 index 000000000..b861b2e09 --- /dev/null +++ b/tests/purus/passing/Import/output/M2/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,20],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"v","body":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[5,17],"start":[5,14]}},"kind":"Var","type":{"annotation":[{"end":[3,23],"name":"tests/purus/passing/Import/M1.purs","start":[3,7]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[3,21],"name":"tests/purus/passing/Import/M1.purs","start":[3,19]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":0,"type":{"annotation":[{"end":[3,23],"name":"tests/purus/passing/Import/M1.purs","start":[3,17]},[]],"contents":[{"annotation":[{"end":[3,23],"name":"tests/purus/passing/Import/M1.purs","start":[3,17]},[]],"contents":[{"annotation":[{"end":[3,21],"name":"tests/purus/passing/Import/M1.purs","start":[3,19]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,18],"name":"tests/purus/passing/Import/M1.purs","start":[3,17]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[3,23],"name":"tests/purus/passing/Import/M1.purs","start":[3,22]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"foo","moduleName":["M1"]}},"annotation":{"meta":null,"sourceSpan":{"end":[5,20],"start":[5,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[5,20],"start":[5,18]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":42}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"t1","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"t1","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"main"}],"exports":["main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,20],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,20],"start":[1,1]}},"moduleName":["M1"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,20],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M2"],"modulePath":"tests/purus/passing/Import/M2.purs","reExports":{},"sourceSpan":{"end":[5,20],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/Import/output/M2/index.cfn.pretty b/tests/purus/passing/Import/output/M2/index.cfn.pretty new file mode 100644 index 000000000..ef851f528 --- /dev/null +++ b/tests/purus/passing/Import/output/M2/index.cfn.pretty @@ -0,0 +1,14 @@ +M2 (tests/purus/passing/Import/M2.purs) +Imported Modules: + Builtin, + M1, + Prim +Exports: + main +Re-Exports: + +Foreign: + +Declarations: +main :: forall (t1 :: Type). t1 -> Int +main = \(v: t1) -> (foo: forall (a :: Type). a -> a) (42: Int) \ No newline at end of file diff --git a/tests/purus/passing/Import/output/package.json b/tests/purus/passing/Import/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/Import/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ImportExplicit/M1.purs b/tests/purus/passing/ImportExplicit/M1.purs new file mode 100644 index 000000000..cf27f2df6 --- /dev/null +++ b/tests/purus/passing/ImportExplicit/M1.purs @@ -0,0 +1,4 @@ +module M1 where + +data X = X | Y +data Z = Z diff --git a/tests/purus/passing/ImportExplicit/output/M1/externs.cbor b/tests/purus/passing/ImportExplicit/output/M1/externs.cbor new file mode 100644 index 000000000..5699a961d Binary files /dev/null and b/tests/purus/passing/ImportExplicit/output/M1/externs.cbor differ diff --git a/tests/purus/passing/ImportExplicit/output/M1/index.cfn b/tests/purus/passing/ImportExplicit/output/M1/index.cfn new file mode 100644 index 000000000..2ef231438 --- /dev/null +++ b/tests/purus/passing/ImportExplicit/output/M1/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"X":["data",[],[{"dataCtorAnn":[{"end":[3,11],"name":"tests/purus/passing/ImportExplicit/M1.purs","start":[3,8]},[]],"dataCtorFields":[],"dataCtorName":"X"},{"dataCtorAnn":[{"end":[3,15],"name":"tests/purus/passing/ImportExplicit/M1.purs","start":[3,12]},[]],"dataCtorFields":[],"dataCtorName":"Y"}]],"Z":["data",[],[{"dataCtorAnn":[{"end":[4,11],"name":"tests/purus/passing/ImportExplicit/M1.purs","start":[4,8]},[]],"dataCtorFields":[],"dataCtorName":"Z"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,11],"start":[4,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,11],"start":[4,1]}},"constructorName":"Z","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["M1"],"Z"],"tag":"TypeConstructor"},"typeName":"Z"},"identifier":"Z"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"constructorName":"X","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["M1"],"X"],"tag":"TypeConstructor"},"typeName":"X"},"identifier":"X"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,15],"start":[3,1]}},"constructorName":"Y","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["M1"],"X"],"tag":"TypeConstructor"},"typeName":"X"},"identifier":"Y"}],"exports":["X","Y","Z"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,11],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,11],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M1"],"modulePath":"tests/purus/passing/ImportExplicit/M1.purs","reExports":{},"sourceSpan":{"end":[4,11],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ImportExplicit/output/M1/index.cfn.pretty b/tests/purus/passing/ImportExplicit/output/M1/index.cfn.pretty new file mode 100644 index 000000000..6477aa1e8 --- /dev/null +++ b/tests/purus/passing/ImportExplicit/output/M1/index.cfn.pretty @@ -0,0 +1,21 @@ +M1 (tests/purus/passing/ImportExplicit/M1.purs) +Imported Modules: + Builtin, + Prim +Exports: + X, + Y, + Z +Re-Exports: + +Foreign: + +Declarations: +Z :: Z +Z = Z + +X :: X +X = X + +Y :: X +Y = Y \ No newline at end of file diff --git a/tests/purus/passing/ImportExplicit/output/package.json b/tests/purus/passing/ImportExplicit/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ImportExplicit/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ImportQualified/M1.purs b/tests/purus/passing/ImportQualified/M1.purs new file mode 100644 index 000000000..719a1a03e --- /dev/null +++ b/tests/purus/passing/ImportQualified/M1.purs @@ -0,0 +1,3 @@ +module M1 where + +log x = x diff --git a/tests/purus/passing/ImportQualified/output/M1/externs.cbor b/tests/purus/passing/ImportQualified/output/M1/externs.cbor new file mode 100644 index 000000000..c11ea91f9 Binary files /dev/null and b/tests/purus/passing/ImportQualified/output/M1/externs.cbor differ diff --git a/tests/purus/passing/ImportQualified/output/M1/index.cfn b/tests/purus/passing/ImportQualified/output/M1/index.cfn new file mode 100644 index 000000000..55c883ec1 --- /dev/null +++ b/tests/purus/passing/ImportQualified/output/M1/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,10],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,10],"start":[3,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[3,10],"start":[3,9]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"t1","tag":"TypeVar"},"value":{"identifier":"x","sourcePos":[3,1]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"t1","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"t1","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"t1","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"log"}],"exports":["log"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,10],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M1"],"modulePath":"tests/purus/passing/ImportQualified/M1.purs","reExports":{},"sourceSpan":{"end":[3,10],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ImportQualified/output/M1/index.cfn.pretty b/tests/purus/passing/ImportQualified/output/M1/index.cfn.pretty new file mode 100644 index 000000000..f44bba751 --- /dev/null +++ b/tests/purus/passing/ImportQualified/output/M1/index.cfn.pretty @@ -0,0 +1,13 @@ +M1 (tests/purus/passing/ImportQualified/M1.purs) +Imported Modules: + Builtin, + Prim +Exports: + log +Re-Exports: + +Foreign: + +Declarations: +log :: forall (t1 :: Type). t1 -> t1 +log = \(x: t1) -> (x: t1) \ No newline at end of file diff --git a/tests/purus/passing/ImportQualified/output/package.json b/tests/purus/passing/ImportQualified/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ImportQualified/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs b/tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs new file mode 100644 index 000000000..c96669335 --- /dev/null +++ b/tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs @@ -0,0 +1,4 @@ +module ImportedClassName where + +class ClassName a where + foo :: a -> Int diff --git a/tests/purus/passing/InstanceUnnamedSimilarClassName/output/ImportedClassName/externs.cbor b/tests/purus/passing/InstanceUnnamedSimilarClassName/output/ImportedClassName/externs.cbor new file mode 100644 index 000000000..a00d76580 Binary files /dev/null and b/tests/purus/passing/InstanceUnnamedSimilarClassName/output/ImportedClassName/externs.cbor differ diff --git a/tests/purus/passing/InstanceUnnamedSimilarClassName/output/ImportedClassName/index.cfn b/tests/purus/passing/InstanceUnnamedSimilarClassName/output/ImportedClassName/index.cfn new file mode 100644 index 000000000..071615fe4 --- /dev/null +++ b/tests/purus/passing/InstanceUnnamedSimilarClassName/output/ImportedClassName/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"ClassName$Dict":["newtype",[["a",null]],[{"dataCtorAnn":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[3,1]},[]],"dataCtorFields":[[{"Ident":"dict"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["foo",{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,14],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,11],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}]],"dataCtorName":"ClassName$Dict"}]]},"decls":[{"annotation":{"meta":{"metaType":"IsTypeClassConstructor"},"sourceSpan":{"end":[4,18],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[4,18],"start":[3,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[3,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["foo",{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,14],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,11],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["foo",{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,14],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,11],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["foo",{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,14],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,11],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"ClassName$Dict"},{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,3]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,3]}},"argument":"dict","body":{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,3]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[4,18],"start":[4,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,3]}},"binderType":"VarBinder","identifier":"v"}],"constructorName":{"identifier":"ClassName$Dict","moduleName":["ImportedClassName"]},"typeName":{"identifier":"ClassName$Dict","moduleName":["ImportedClassName"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,3]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["foo",{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,14],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[4,14],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,12]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"v","sourcePos":[4,3]}},"fieldName":"foo","kind":"Accessor","type":{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,14],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,11],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["ImportedClassName"],"ClassName$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"dict","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,14],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,11],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":0,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["ImportedClassName"],"ClassName$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":[{"annotation":[{"end":[4,14],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[4,11],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[4,18],"name":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","start":[4,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"}},"identifier":"foo"}],"exports":["foo"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[1,1]}},"moduleName":["ImportedClassName"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["ImportedClassName"],"modulePath":"tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs","reExports":{},"sourceSpan":{"end":[4,18],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/InstanceUnnamedSimilarClassName/output/ImportedClassName/index.cfn.pretty b/tests/purus/passing/InstanceUnnamedSimilarClassName/output/ImportedClassName/index.cfn.pretty new file mode 100644 index 000000000..c9630c2e8 --- /dev/null +++ b/tests/purus/passing/InstanceUnnamedSimilarClassName/output/ImportedClassName/index.cfn.pretty @@ -0,0 +1,20 @@ +ImportedClassName (tests/purus/passing/InstanceUnnamedSimilarClassName/ImportedClassName.purs) +Imported Modules: + Builtin, + ImportedClassName, + Prim +Exports: + foo +Re-Exports: + +Foreign: + +Declarations: +ClassName$Dict :: forall a. { foo :: a -> Int } -> { foo :: a -> Int } +ClassName$Dict = \(x: { foo :: a -> Int }) -> (x: { foo :: a -> Int }) + +foo :: forall (@a :: Type). ClassName$Dict a -> a -> Int +foo = + \(dict: ClassName$Dict a) -> + case (dict: ClassName$Dict a) of + ClassName$Dict v -> (v: { foo :: a -> Int }).foo \ No newline at end of file diff --git a/tests/purus/passing/InstanceUnnamedSimilarClassName/output/package.json b/tests/purus/passing/InstanceUnnamedSimilarClassName/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/InstanceUnnamedSimilarClassName/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/Misc/Lib.purs b/tests/purus/passing/Misc/Lib.purs new file mode 100644 index 000000000..4f25254a2 --- /dev/null +++ b/tests/purus/passing/Misc/Lib.purs @@ -0,0 +1,256 @@ +module Lib where + +{- Type Classes -} +-- Single Param +class Eq a where + eq :: a -> a -> Boolean + +minus :: Int -> Int -> Int +minus _ _ = 42 + +instance Eq Int where + eq _ _ = true + +testEq :: Boolean +testEq = eq 1 2 + +{- Tomasz's Counterexample -} +workingEven :: Int -> Int +workingEven n = + if n `eq` 0 then 1 + else 42 + +brokenEven :: Int -> Int -- N.B. shouldn't be broken anymore :) +brokenEven n = + if n `eq` 0 then 1 + else brokenEven (n `minus` 2) + +-- Multi Param +class Eq2 a b where + eq2 :: a -> b -> Boolean + +instance Eq2 Int Boolean where + eq2 _ _ = true + +testEq2 :: Boolean +testEq2 = eq2 101 false + +{- Binders (also tests a bunch of other things by happenstance) -} + +-- Unit test type for inferBinder' +data TestBinderSum = + ConInt Int + | ConInts (Array Int) + | ConBoolean Boolean + | ConString String + | ConChar Char + | ConNested TestBinderSum + | ConQuantified (forall x. x -> Int) + | ConConstrained (forall x. Eq x => x -> Int) -- kind of nonsensical + | ConObject {objField :: Int} + | ConObjectQuantified {objFieldQ :: forall x. x -> Int} + +testBinders :: TestBinderSum -> Int +testBinders x = case x of + a@(ConInt 3) -> 1 -- NamedBinder, ConstructorBinder, Int LitBinder + ConInt a -> a -- ConstructorBinder enclosing VarBinder + ConInts ([3] :: Array Int) -> 2 -- Array LitBinder, TypedBinder + ConInts [a,b] -> b -- VarBinders enclosed in Array LitBinder + ConBoolean true -> 4 -- Bool LitBinder + ConChar '\n' -> 5 -- Char LitBinder + ConNested (ConInt 2) -> 6 -- Nested ConstructorBinders + ConQuantified f -> f "hello" + ConConstrained f -> f 2 + ConNested other -> 7 + ConObject obj -> obj.objField + ConObjectQuantified objQ -> objQ.objFieldQ "world" + ConObject {objField: f} -> f + _ -> 0 + + +{- Binding groups (with and w/o type anns) -} +mutuallyRecursiveBindingGroup :: Int +mutuallyRecursiveBindingGroup = + let f :: Int -> Int + f x = g 2 + h :: Int -> Int -> Int + h x y = y + g :: Int -> Int + g y = h (f y) 3 + in g 3 + + +mutuallyRecursiveBindingGroupNoTypes :: Int +mutuallyRecursiveBindingGroupNoTypes = + let f' x = g' 2 + h' x y = y + g' y = h' (f' y) 3 + in g' 3 + +nestedBinds :: Int +nestedBinds = + let f :: Int -> Int + f _ = 4 + + g :: forall (a :: Type). a -> Int + g _ = 5 + + h = let i = g "hello" + j = f i + in f j + in h + +{- Data declarations -} +data ADataRec = ADataRec {hello :: Int, world :: Boolean} + +newtype ANewtypeRec = ANewTypeRec {foo :: Int} + +data ASum = Constr1 Int | Constr2 Boolean + +{- lits -} +anIntLit :: Int +anIntLit = 1 + +aStringLit :: String +aStringLit = "woop" + +aVal :: Int +aVal = 1 + +testasum :: ASum -> Int +testasum x = case x of + Constr1 y -> 1 + Constr2 z -> 2 + + +aBool :: Boolean +aBool = true + +aList :: Array Int +aList = [1,2,3,4,5] + +{- Functions -} + +aFunction :: forall x. x -> (forall y. y -> Int) -> Int +aFunction any f = f any + +aFunction2 :: Int -> Array Int +aFunction2 x = [x,1] + +aFunction3 :: Int -> Int +aFunction3 x = if (eq x 2) then 4 else 1 + +aFunction4 :: forall (r :: Row Type). {a :: Int | r} -> Int +aFunction4 r = r.a + +aFunction5 :: Int +aFunction5 = aFunction4 {a: 2} + +aFunction6 :: Int +aFunction6 = aFunction [] go + where + go :: forall (z :: Type). z -> Int + go _ = 10 + +-- main = aFunction4 {a: 2, b: 3} + +recF1 :: forall x. x -> Int +recF1 x = recG1 x + +recG1 :: forall x. x -> Int +recG1 x = recF1 x + +testBuiltin :: Int +testBuiltin = Builtin.addInteger 1 2 + +-- main = aFunction4 {a: 101, b: "hello"} -- recF1 "hello" + +plus :: Int -> Int -> Int +plus a b = Builtin.addInteger a b + +infixr 5 plus as + + +main = plus 1 1 + +guardedCase :: Int -> Int -> Int +guardedCase w x = case w, x of + y, z | eq y 2 + , aPred y + , eq z 0 + , eq y nestedBinds -> 2 + _, _ -> 0 + +nestedApplications :: Int +nestedApplications = i (f (g (h 2))) 4 + where + i x _ = x + f x = x + g _ = 5 + h = case _ of + 2 -> 3 + _ -> 5 + +{- Objects -} + +anObj :: {foo :: Int} +anObj = {foo: 3} + +objUpdate :: {foo :: Int} +objUpdate = anObj {foo = 4} + +polyInObj :: {bar :: forall x. x -> Int, baz :: Int} +polyInObj = {bar: go, baz : 100} + where + go :: forall y. y -> Int + go _ = 5 + +polyInObjMatch :: Int +polyInObjMatch = case polyInObj of + {bar: f, baz: _} -> f "hello" + +aPred :: Int -> Boolean +aPred _ = true + +cons :: forall a. a -> Array a -> Array a +cons x xs = [x] + +emptyList = [] + +consEmptyList1 = cons 1 emptyList + +consEmptyList2 = cons "hello" emptyList + +id :: forall t. t -> t +id x = x + +objForall :: forall a b. {getIdA :: a -> a, getIdB :: b -> b} +objForall = {getIdA: id, getIdB: id} + +arrForall :: forall a. Array (a -> a) +arrForall = [id] + +{- We should probably just remove guarded case branches, see slack msg +guardedCase :: Int +guardedCase = case polyInObj of + {bar: _, baz: x} + | eq @Int x 4 -> x + _ -> 0 +-} + +{- +id :: forall a. a -> a +id a = a + +-- Works with signature, throws without +-- inner :: { getId :: forall a. a -> a} +inner = {getId: id} +-} + +class Eq a <= Ord a where + compare :: a -> a -> Int + +instance Ord Int where + compare _ _ = 42 + +testEqViaOrd :: forall a. Ord a => a -> a -> Boolean +testEqViaOrd a b = eq a b diff --git a/tests/purus/passing/Misc/output/Lib/externs.cbor b/tests/purus/passing/Misc/output/Lib/externs.cbor new file mode 100644 index 000000000..68a46b5d3 Binary files /dev/null and b/tests/purus/passing/Misc/output/Lib/externs.cbor differ diff --git a/tests/purus/passing/Misc/output/Lib/index.cfn b/tests/purus/passing/Misc/output/Lib/index.cfn new file mode 100644 index 000000000..04581c785 --- /dev/null +++ b/tests/purus/passing/Misc/output/Lib/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"ADataRec":["data",[],[{"dataCtorAnn":[{"end":[104,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,15]},[]],"dataCtorFields":[[{"Ident":"value0"},{"annotation":[{"end":[104,58],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,26]},[]],"contents":[{"annotation":[{"end":[104,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,26]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[104,39],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,27]},[]],"contents":["hello",{"annotation":[{"end":[104,39],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,36]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[104,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,41]},[]],"contents":["world",{"annotation":[{"end":[104,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,50]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},{"annotation":[{"end":[104,58],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,57]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"}]],"dataCtorName":"ADataRec"}]],"ANewtypeRec":["newtype",[],[{"dataCtorAnn":[{"end":[106,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,21]},[]],"dataCtorFields":[[{"Ident":"value0"},{"annotation":[{"end":[106,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,35]},[]],"contents":[{"annotation":[{"end":[106,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,35]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[106,46],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,36]},[]],"contents":["foo",{"annotation":[{"end":[106,46],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,43]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[106,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,46]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}]],"dataCtorName":"ANewTypeRec"}]],"ASum":["data",[],[{"dataCtorAnn":[{"end":[108,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[108,11]},[]],"dataCtorFields":[[{"Ident":"value0"},{"annotation":[{"end":[108,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[108,21]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}]],"dataCtorName":"Constr1"},{"dataCtorAnn":[{"end":[108,34],"name":"tests/purus/passing/Misc/Lib.purs","start":[108,25]},[]],"dataCtorFields":[[{"Ident":"value0"},{"annotation":[{"end":[108,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[108,35]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}]],"dataCtorName":"Constr2"}]],"Eq$Dict":["newtype",[["a",null]],[{"dataCtorAnn":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[5,1]},[{"BlockComment":" Type Classes "},{"LineComment":" Single Param"}]],"dataCtorFields":[[{"Ident":"dict"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq",{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}]],"dataCtorName":"Eq$Dict"}]],"Eq2$Dict":["newtype",[["a",null],["b",null]],[{"dataCtorAnn":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[29,1]},[{"LineComment":" Multi Param"}]],"dataCtorFields":[[{"Ident":"dict"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq2",{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}]],"dataCtorName":"Eq2$Dict"}]],"Ord$Dict":["newtype",[["a",null]],[{"dataCtorAnn":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[249,1]},[{"BlockComment":" We should probably just remove guarded case branches, see slack msg\nguardedCase :: Int\nguardedCase = case polyInObj of\n {bar: _, baz: x}\n | eq @Int x 4 -> x\n _ -> 0\n"},{"BlockComment":"\nid :: forall a. a -> a\nid a = a\n\n-- Works with signature, throws without\n-- inner :: { getId :: forall a. a -> a}\ninner = {getId: id}\n"}]],"dataCtorFields":[[{"Ident":"dict"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["compare",{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["Eq0",{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[249,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[249,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"}]],"dataCtorName":"Ord$Dict"}]]},"decls":[{"annotation":{"meta":{"metaType":"IsTypeClassConstructor"},"sourceSpan":{"end":[30,27],"start":[29,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[30,27],"start":[29,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[30,27],"start":[29,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq2",{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"b","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq2",{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq2",{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"Eq2$Dict"},{"annotation":{"meta":{"metaType":"IsTypeClassConstructor"},"sourceSpan":{"end":[6,26],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[6,26],"start":[5,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[6,26],"start":[5,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq",{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq",{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq",{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"Eq$Dict"},{"annotation":{"meta":{"metaType":"IsTypeClassConstructor"},"sourceSpan":{"end":[250,27],"start":[249,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[250,27],"start":[249,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[250,27],"start":[249,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["compare",{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["Eq0",{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[249,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[249,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["compare",{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["Eq0",{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[249,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[249,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["compare",{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["Eq0",{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[249,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[249,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"Ord$Dict"},{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"constructorName":"ConInt","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[42,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[42,12]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"TestBinderSum"},"identifier":"ConInt"},{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"constructorName":"ConInts","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[43,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[43,14]},[]],"contents":[{"annotation":[{"end":[43,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[43,14]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[43,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[43,20]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"TestBinderSum"},"identifier":"ConInts"},{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"constructorName":"ConBoolean","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[44,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[44,16]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"TestBinderSum"},"identifier":"ConBoolean"},{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"constructorName":"ConString","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[45,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[45,15]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"TestBinderSum"},"identifier":"ConString"},{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"constructorName":"ConChar","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[46,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[46,13]},[]],"contents":[["Prim"],"Char"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"TestBinderSum"},"identifier":"ConChar"},{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"constructorName":"ConNested","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"TestBinderSum"},"identifier":"ConNested"},{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"constructorName":"ConQuantified","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[48,38],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,20]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[48,34],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,32]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[48,38],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,30]},[]],"contents":[{"annotation":[{"end":[48,38],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,30]},[]],"contents":[{"annotation":[{"end":[48,34],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,32]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[48,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,30]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[48,38],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,35]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"TestBinderSum"},"identifier":"ConQuantified"},{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"constructorName":"ConConstrained","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[49,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,21]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[49,35],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,31]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[49,35],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,34]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[49,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,39]},[]],"contents":[{"annotation":[{"end":[49,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,39]},[]],"contents":[{"annotation":[{"end":[49,43],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,41]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[49,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,39]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[49,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,44]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"TestBinderSum"},"identifier":"ConConstrained"},{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"constructorName":"ConObject","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[50,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,15]},[]],"contents":[{"annotation":[{"end":[50,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,15]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[50,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,16]},[]],"contents":["objField",{"annotation":[{"end":[50,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,28]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[50,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,31]},[]],"contents":[{"annotation":[{"end":[50,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,31]},[]],"tag":"REmpty"},{"annotation":[{"end":[50,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,28]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"TestBinderSum"},"identifier":"ConObject"},{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[51,58],"start":[41,1]}},"constructorName":"ConObjectQuantified","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[51,58],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,25]},[]],"contents":[{"annotation":[{"end":[51,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,25]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,26]},[]],"contents":["objFieldQ",{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,39]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[51,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,51]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,49]},[]],"contents":[{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,49]},[]],"contents":[{"annotation":[{"end":[51,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,51]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[51,50],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,49]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,54]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},{"annotation":[{"end":[51,58],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,57]},[]],"contents":[{"annotation":[{"end":[51,58],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,57]},[]],"tag":"REmpty"},{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,39]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"TestBinderSum"},"identifier":"ConObjectQuantified"},{"annotation":{"meta":null,"sourceSpan":{"end":[108,42],"start":[108,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[108,42],"start":[108,1]}},"constructorName":"Constr1","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[108,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[108,21]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"ASum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"ASum"},"identifier":"Constr1"},{"annotation":{"meta":null,"sourceSpan":{"end":[108,42],"start":[108,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[108,42],"start":[108,1]}},"constructorName":"Constr2","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[108,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[108,35]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"ASum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"ASum"},"identifier":"Constr2"},{"annotation":{"meta":null,"sourceSpan":{"end":[106,47],"start":[106,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[106,47],"start":[106,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[106,47],"start":[106,1]}},"kind":"Var","type":{"annotation":[{"end":[106,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,35]},[]],"contents":[{"annotation":[{"end":[106,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,35]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[106,46],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,36]},[]],"contents":["foo",{"annotation":[{"end":[106,46],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,43]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[106,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,46]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[106,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,35]},[]],"contents":[{"annotation":[{"end":[106,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,35]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[106,46],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,36]},[]],"contents":["foo",{"annotation":[{"end":[106,46],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,43]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[106,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,46]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[106,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,35]},[]],"contents":[{"annotation":[{"end":[106,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,35]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[106,46],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,36]},[]],"contents":["foo",{"annotation":[{"end":[106,46],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,43]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[106,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[106,46]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"ANewTypeRec"},{"annotation":{"meta":null,"sourceSpan":{"end":[104,58],"start":[104,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[104,58],"start":[104,1]}},"constructorName":"ADataRec","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[104,58],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,26]},[]],"contents":[{"annotation":[{"end":[104,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,26]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[104,39],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,27]},[]],"contents":["hello",{"annotation":[{"end":[104,39],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,36]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[104,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,41]},[]],"contents":["world",{"annotation":[{"end":[104,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,50]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},{"annotation":[{"end":[104,58],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,57]},[]],"contents":[{"annotation":[{"end":[104,58],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,57]},[]],"tag":"REmpty"},{"annotation":[{"end":[104,39],"name":"tests/purus/passing/Misc/Lib.purs","start":[104,36]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"ADataRec"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"ADataRec"},"identifier":"ADataRec"},{"annotation":{"meta":null,"sourceSpan":{"end":[12,16],"start":[11,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[12,16],"start":[11,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq",{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"Eq$Dict","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[12,16],"start":[11,1]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[12,16],"start":[11,1]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq",{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[["eq",{"annotation":{"meta":null,"sourceSpan":{"end":[12,16],"start":[12,3]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[12,16],"start":[12,3]}},"argument":"v1","body":{"annotation":{"meta":null,"sourceSpan":{"end":[12,16],"start":[12,12]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"literalType":"BooleanLiteral","value":true}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}}]]}},"kind":"App"},"identifier":"eqInt"},{"annotation":{"meta":null,"sourceSpan":{"end":[253,19],"start":[252,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[253,19],"start":[252,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["compare",{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["Eq0",{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Ord$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"Ord$Dict","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[253,19],"start":[252,1]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[253,19],"start":[252,1]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["compare",{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["Eq0",{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[["Eq0",{"annotation":{"meta":null,"sourceSpan":{"end":[253,19],"start":[252,1]}},"argument":"$__unused","body":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"eqInt","moduleName":["Lib"]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}}],["compare",{"annotation":{"meta":null,"sourceSpan":{"end":[253,19],"start":[253,3]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[253,19],"start":[253,3]}},"argument":"v1","body":{"annotation":{"meta":null,"sourceSpan":{"end":[253,19],"start":[253,17]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":42}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[252,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[252,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}}]]}},"kind":"App"},"identifier":"ordInt"},{"annotation":{"meta":null,"sourceSpan":{"end":[33,17],"start":[32,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[33,17],"start":[32,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq2",{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[32,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[32,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[32,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[32,18]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq2$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[32,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[32,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[32,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[32,18]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"Eq2$Dict","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[33,17],"start":[32,1]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[33,17],"start":[32,1]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq2",{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[32,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[32,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[32,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[32,18]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[["eq2",{"annotation":{"meta":null,"sourceSpan":{"end":[33,17],"start":[33,3]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[33,17],"start":[33,3]}},"argument":"v1","body":{"annotation":{"meta":null,"sourceSpan":{"end":[33,17],"start":[33,13]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"literalType":"BooleanLiteral","value":true}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[32,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[32,18]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[32,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[32,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[32,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[32,18]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}}]]}},"kind":"App"},"identifier":"eq2IntBoolean"},{"annotation":{"meta":null,"sourceSpan":{"end":[120,24],"start":[120,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[123,17],"start":[121,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[123,17],"start":[121,14]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[122,12],"start":[122,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[122,12],"start":[122,11]}},"binderType":"VarBinder","identifier":"y"}],"constructorName":{"identifier":"Constr1","moduleName":["Lib"]},"typeName":{"identifier":"ASum","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[122,17],"start":[122,16]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[123,12],"start":[123,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[123,12],"start":[123,11]}},"binderType":"VarBinder","identifier":"z"}],"constructorName":{"identifier":"Constr2","moduleName":["Lib"]},"typeName":{"identifier":"ASum","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[123,17],"start":[123,16]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[121,20],"start":[121,19]}},"kind":"Var","type":{"annotation":[{"end":[120,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[120,13]},[]],"contents":[["Lib"],"ASum"],"tag":"TypeConstructor"},"value":{"identifier":"x","sourcePos":[121,1]}}],"kind":"Case","type":{"annotation":[{"end":[120,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[120,21]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[120,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[120,13]},[]],"contents":[["Lib"],"ASum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[120,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[120,21]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"testasum"},{"annotation":{"meta":null,"sourceSpan":{"end":[163,19],"start":[163,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[164,33],"start":[164,15]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"addInteger","moduleName":["Builtin"]}},"annotation":{"meta":null,"sourceSpan":{"end":[164,35],"start":[164,15]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[164,35],"start":[164,34]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[164,37],"start":[164,15]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[164,37],"start":[164,36]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"kind":"App"},"identifier":"testBuiltin"},{"annotation":{"meta":null,"sourceSpan":{"end":[53,37],"start":[53,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[68,17],"start":[54,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[68,17],"start":[54,17]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[55,15],"start":[55,3]}},"binder":{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[55,14],"start":[55,6]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[55,14],"start":[55,13]}},"binderType":"LiteralBinder","literal":{"literalType":"IntLiteral","value":3}}],"constructorName":{"identifier":"ConInt","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}},"binderType":"NamedBinder","identifier":"a"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[55,21],"start":[55,20]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[56,11],"start":[56,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[56,11],"start":[56,10]}},"binderType":"VarBinder","identifier":"a"}],"constructorName":{"identifier":"ConInt","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[56,16],"start":[56,15]}},"kind":"Var","type":{"annotation":[{"end":[42,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[42,12]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"a","sourcePos":[56,10]}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[57,29],"start":[57,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[57,15],"start":[57,12]}},"binderType":"LiteralBinder","literal":{"literalType":"ArrayLiteral","value":[{"annotation":{"meta":null,"sourceSpan":{"end":[57,14],"start":[57,13]}},"binderType":"LiteralBinder","literal":{"literalType":"IntLiteral","value":3}}]}}],"constructorName":{"identifier":"ConInts","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[57,34],"start":[57,33]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[58,16],"start":[58,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[58,16],"start":[58,11]}},"binderType":"LiteralBinder","literal":{"literalType":"ArrayLiteral","value":[{"annotation":{"meta":null,"sourceSpan":{"end":[58,13],"start":[58,12]}},"binderType":"VarBinder","identifier":"a"},{"annotation":{"meta":null,"sourceSpan":{"end":[58,15],"start":[58,14]}},"binderType":"VarBinder","identifier":"b"}]}}],"constructorName":{"identifier":"ConInts","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[58,21],"start":[58,20]}},"kind":"Var","type":{"annotation":[{"end":[43,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[43,20]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"b","sourcePos":[58,14]}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[59,18],"start":[59,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[59,18],"start":[59,14]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"constructorName":{"identifier":"ConBoolean","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[59,24],"start":[59,23]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":4}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[60,15],"start":[60,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[60,15],"start":[60,11]}},"binderType":"LiteralBinder","literal":{"literalType":"CharLiteral","value":"\n"}}],"constructorName":{"identifier":"ConChar","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[60,20],"start":[60,19]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":5}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[61,23],"start":[61,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[61,22],"start":[61,14]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[61,22],"start":[61,21]}},"binderType":"LiteralBinder","literal":{"literalType":"IntLiteral","value":2}}],"constructorName":{"identifier":"ConInt","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"constructorName":{"identifier":"ConNested","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[61,28],"start":[61,27]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":6}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[62,18],"start":[62,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[62,18],"start":[62,17]}},"binderType":"VarBinder","identifier":"f"}],"constructorName":{"identifier":"ConQuantified","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[62,23],"start":[62,22]}},"kind":"Var","type":{"annotation":[{"end":[48,38],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,20]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[48,34],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,32]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[48,38],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,30]},[]],"contents":[{"annotation":[{"end":[48,38],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,30]},[]],"contents":[{"annotation":[{"end":[48,34],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,32]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[48,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,30]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[48,38],"name":"tests/purus/passing/Misc/Lib.purs","start":[48,35]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"f","sourcePos":[62,17]}},"annotation":{"meta":null,"sourceSpan":{"end":[62,31],"start":[62,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[62,31],"start":[62,24]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"hello"}},"kind":"App"},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[63,19],"start":[63,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[63,19],"start":[63,18]}},"binderType":"VarBinder","identifier":"f"}],"constructorName":{"identifier":"ConConstrained","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[63,24],"start":[63,23]}},"kind":"Var","type":{"annotation":[{"end":[49,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,21]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[49,35],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,31]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[49,35],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,34]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[49,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,39]},[]],"contents":[{"annotation":[{"end":[49,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,39]},[]],"contents":[{"annotation":[{"end":[49,43],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,41]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[49,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,39]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[49,47],"name":"tests/purus/passing/Misc/Lib.purs","start":[49,44]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"f","sourcePos":[63,18]}},"annotation":{"meta":null,"sourceSpan":{"end":[63,26],"start":[63,23]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"eqInt","moduleName":["Lib"]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[63,26],"start":[63,23]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[63,26],"start":[63,25]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"kind":"App"},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[64,18],"start":[64,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[64,18],"start":[64,13]}},"binderType":"VarBinder","identifier":"other"}],"constructorName":{"identifier":"ConNested","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[64,23],"start":[64,22]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":7}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[65,16],"start":[65,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[65,16],"start":[65,13]}},"binderType":"VarBinder","identifier":"obj"}],"constructorName":{"identifier":"ConObject","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[65,32],"start":[65,20]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[65,23],"start":[65,20]}},"kind":"Var","type":{"annotation":[{"end":[50,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,15]},[]],"contents":[{"annotation":[{"end":[50,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,15]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[50,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,16]},[]],"contents":["objField",{"annotation":[{"end":[50,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,28]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[50,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,31]},[]],"contents":[{"annotation":[{"end":[50,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,31]},[]],"tag":"REmpty"},{"annotation":[{"end":[50,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,28]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"obj","sourcePos":[65,13]}},"fieldName":"objField","kind":"Accessor","type":{"annotation":[{"end":[53,37],"name":"tests/purus/passing/Misc/Lib.purs","start":[53,34]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[66,27],"start":[66,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[66,27],"start":[66,23]}},"binderType":"VarBinder","identifier":"objQ"}],"constructorName":{"identifier":"ConObjectQuantified","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[66,45],"start":[66,31]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[66,35],"start":[66,31]}},"kind":"Var","type":{"annotation":[{"end":[51,58],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,25]},[]],"contents":[{"annotation":[{"end":[51,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,25]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,26]},[]],"contents":["objFieldQ",{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,39]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[51,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,51]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,49]},[]],"contents":[{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,49]},[]],"contents":[{"annotation":[{"end":[51,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,51]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[51,50],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,49]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,54]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},{"annotation":[{"end":[51,58],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,57]},[]],"contents":[{"annotation":[{"end":[51,58],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,57]},[]],"tag":"REmpty"},{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,39]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"objQ","sourcePos":[66,23]}},"fieldName":"objFieldQ","kind":"Accessor","type":{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,49]},[]],"contents":[{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,49]},[]],"contents":[{"annotation":[{"end":[51,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,51]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[51,57],"name":"tests/purus/passing/Misc/Lib.purs","start":[51,54]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"annotation":{"meta":null,"sourceSpan":{"end":[66,53],"start":[66,31]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[66,53],"start":[66,46]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"world"}},"kind":"App"},"isGuarded":false},{"binders":[{"annotation":{"meta":{"constructorType":"SumType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[67,26],"start":[67,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[67,26],"start":[67,13]}},"binderType":"LiteralBinder","literal":{"literalType":"ObjectLiteral","value":[["objField",{"annotation":{"meta":null,"sourceSpan":{"end":[67,25],"start":[67,24]}},"binderType":"VarBinder","identifier":"f"}]]}}],"constructorName":{"identifier":"ConObject","moduleName":["Lib"]},"typeName":{"identifier":"TestBinderSum","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[67,31],"start":[67,30]}},"kind":"Var","type":{"annotation":[{"end":[50,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[50,28]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"f","sourcePos":[67,24]}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[68,4],"start":[68,3]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[68,17],"start":[68,16]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":0}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[54,23],"start":[54,22]}},"kind":"Var","type":{"annotation":[{"end":[53,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[53,16]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"},"value":{"identifier":"x","sourcePos":[54,1]}}],"kind":"Case","type":{"annotation":[{"end":[53,37],"name":"tests/purus/passing/Misc/Lib.purs","start":[53,34]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[53,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[53,16]},[]],"contents":[["Lib"],"TestBinderSum"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[53,37],"name":"tests/purus/passing/Misc/Lib.purs","start":[53,34]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"testBinders"},{"bindType":"Rec","binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[160,28],"start":[160,1]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[161,18],"start":[161,1]}},"argument":"x","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[161,16],"start":[161,11]}},"kind":"Var","type":{"annotation":[{"end":[157,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,10]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[157,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,22]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":10,"type":{"annotation":[{"end":[157,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,20]},[]],"contents":[{"annotation":[{"end":[157,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,20]},[]],"contents":[{"annotation":[{"end":[157,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,22]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[157,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,20]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[157,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,25]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"recF1","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[161,18],"start":[161,11]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[161,18],"start":[161,17]}},"kind":"Var","type":{"annotation":[{"end":[160,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,20]},[]],"contents":"x","tag":"TypeVar"},"value":{"identifier":"x","sourcePos":[161,1]}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[160,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,10]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[160,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,22]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":8,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[160,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,20]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[160,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,25]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"recG1"},{"annotation":{"meta":null,"sourceSpan":{"end":[157,28],"start":[157,1]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[158,18],"start":[158,1]}},"argument":"x","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[158,16],"start":[158,11]}},"kind":"Var","type":{"annotation":[{"end":[160,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,10]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[160,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,22]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":7,"type":{"annotation":[{"end":[160,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,20]},[]],"contents":[{"annotation":[{"end":[160,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,20]},[]],"contents":[{"annotation":[{"end":[160,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,22]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[160,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,20]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[160,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[160,25]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"recG1","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[158,18],"start":[158,11]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[158,18],"start":[158,17]}},"kind":"Var","type":{"annotation":[{"end":[157,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,20]},[]],"contents":"x","tag":"TypeVar"},"value":{"identifier":"x","sourcePos":[158,1]}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[157,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,10]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[157,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,22]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":11,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[157,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,20]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[157,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[157,25]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"recF1"}]},{"annotation":{"meta":null,"sourceSpan":{"end":[201,53],"start":[201,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsWhere"},"sourceSpan":{"end":[202,33],"start":[202,13]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[204,29],"start":[204,5]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[205,13],"start":[205,5]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[205,13],"start":[205,12]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":5}},"kind":"Abs","type":{"annotation":[{"end":[204,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[204,11]},[]],"contents":{"identifier":"y","kind":{"annotation":[{"end":[204,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[204,23]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":15,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[204,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[204,21]},[]],"contents":"y","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[204,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[204,26]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"go"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[202,33],"start":[202,13]}},"kind":"Literal","type":{"annotation":[{"end":[201,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,14]},[]],"contents":[{"annotation":[{"end":[201,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,14]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,15]},[]],"contents":["bar",{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,22]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[201,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,34]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":13,"type":{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,32]},[]],"contents":[{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,32]},[]],"contents":[{"annotation":[{"end":[201,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,34]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[201,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,32]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,37]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},{"annotation":[{"end":[201,52],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,42]},[]],"contents":["baz",{"annotation":[{"end":[201,52],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,49]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[201,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,52]},[]],"contents":[{"annotation":[{"end":[201,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,52]},[]],"tag":"REmpty"},{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,22]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[["baz",{"annotation":{"meta":null,"sourceSpan":{"end":[202,32],"start":[202,29]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":100}}],["bar",{"annotation":{"meta":null,"sourceSpan":{"end":[202,21],"start":[202,19]}},"kind":"Var","type":{"annotation":[{"end":[204,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[204,11]},[]],"contents":{"identifier":"y","kind":{"annotation":[{"end":[204,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[204,23]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":15,"type":{"annotation":[{"end":[204,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[204,21]},[]],"contents":[{"annotation":[{"end":[204,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[204,21]},[]],"contents":[{"annotation":[{"end":[204,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[204,23]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[204,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[204,21]},[]],"contents":"y","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[204,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[204,26]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"go","sourcePos":[204,5]}}]]}},"kind":"Let"},"identifier":"polyInObj"},{"annotation":{"meta":null,"sourceSpan":{"end":[207,22],"start":[207,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[209,32],"start":[208,18]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[209,19],"start":[209,3]}},"binderType":"LiteralBinder","literal":{"literalType":"ObjectLiteral","value":[["bar",{"annotation":{"meta":null,"sourceSpan":{"end":[209,10],"start":[209,9]}},"binderType":"VarBinder","identifier":"f"}],["baz",{"annotation":{"meta":null,"sourceSpan":{"end":[209,18],"start":[209,17]}},"binderType":"NullBinder"}]]}}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[209,24],"start":[209,23]}},"kind":"Var","type":{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,22]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[201,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,34]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":13,"type":{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,32]},[]],"contents":[{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,32]},[]],"contents":[{"annotation":[{"end":[201,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,34]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[201,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,32]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,37]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"f","sourcePos":[209,9]}},"annotation":{"meta":null,"sourceSpan":{"end":[209,32],"start":[209,23]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[209,32],"start":[209,25]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"hello"}},"kind":"App"},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[208,32],"start":[208,23]}},"kind":"Var","type":{"annotation":[{"end":[201,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,14]},[]],"contents":[{"annotation":[{"end":[201,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,14]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,15]},[]],"contents":["bar",{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,22]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[201,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,34]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":13,"type":{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,32]},[]],"contents":[{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,32]},[]],"contents":[{"annotation":[{"end":[201,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,34]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[201,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,32]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,37]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},{"annotation":[{"end":[201,52],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,42]},[]],"contents":["baz",{"annotation":[{"end":[201,52],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,49]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[201,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,52]},[]],"contents":[{"annotation":[{"end":[201,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,52]},[]],"tag":"REmpty"},{"annotation":[{"end":[201,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[201,22]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"polyInObj","moduleName":["Lib"]}}],"kind":"Case","type":{"annotation":[{"end":[207,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[207,19]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"identifier":"polyInObjMatch"},{"annotation":{"meta":null,"sourceSpan":{"end":[168,26],"start":[168,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[169,34],"start":[169,1]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[169,34],"start":[169,1]}},"argument":"b","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[169,30],"start":[169,12]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"addInteger","moduleName":["Builtin"]}},"annotation":{"meta":null,"sourceSpan":{"end":[169,32],"start":[169,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[169,32],"start":[169,31]}},"kind":"Var","type":{"annotation":[{"end":[168,12],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,9]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"a","sourcePos":[169,1]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[169,34],"start":[169,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[169,34],"start":[169,33]}},"kind":"Var","type":{"annotation":[{"end":[168,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"b","sourcePos":[169,1]}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[168,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[168,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,23]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[168,12],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,9]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[168,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,16]},[]],"contents":[{"annotation":[{"end":[168,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,16]},[]],"contents":[{"annotation":[{"end":[168,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,20]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[168,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[168,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,23]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"plus"},{"annotation":{"meta":null,"sourceSpan":{"end":[90,19],"start":[90,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[101,7],"start":[92,3]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[95,41],"start":[95,8]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[96,15],"start":[96,8]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[96,15],"start":[96,14]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":5}},"kind":"Abs","type":{"annotation":[{"end":[95,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,13]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[95,30],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,26]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":18,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[95,34],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,33]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[95,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,38]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"g"},{"annotation":{"meta":null,"sourceSpan":{"end":[92,23],"start":[92,8]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[93,15],"start":[93,8]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[93,15],"start":[93,14]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":4}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[92,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[92,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,20]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"f"},{"annotation":{"meta":null,"sourceSpan":{"end":[100,18],"start":[98,8]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[100,18],"start":[98,12]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[98,29],"start":[98,16]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[98,21],"start":[98,20]}},"kind":"Var","type":{"annotation":[{"end":[95,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,13]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[95,30],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,26]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":18,"type":{"annotation":[{"end":[95,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,33]},[]],"contents":[{"annotation":[{"end":[95,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,33]},[]],"contents":[{"annotation":[{"end":[95,37],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,35]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[95,34],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,33]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[95,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,38]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"g","sourcePos":[95,8]}},"annotation":{"meta":null,"sourceSpan":{"end":[98,29],"start":[98,20]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[98,29],"start":[98,22]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"hello"}},"kind":"App"},"identifier":"i"},{"annotation":{"meta":null,"sourceSpan":{"end":[99,23],"start":[99,16]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[99,21],"start":[99,20]}},"kind":"Var","type":{"annotation":[{"end":[92,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,13]},[]],"contents":[{"annotation":[{"end":[92,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,13]},[]],"contents":[{"annotation":[{"end":[92,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[92,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[92,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,20]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"f","sourcePos":[92,8]}},"annotation":{"meta":null,"sourceSpan":{"end":[99,23],"start":[99,20]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[99,23],"start":[99,22]}},"kind":"Var","type":{"annotation":[{"end":[95,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[95,38]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"i","sourcePos":[98,16]}},"kind":"App"},"identifier":"j"}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[100,16],"start":[100,15]}},"kind":"Var","type":{"annotation":[{"end":[92,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,13]},[]],"contents":[{"annotation":[{"end":[92,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,13]},[]],"contents":[{"annotation":[{"end":[92,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[92,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[92,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,20]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"f","sourcePos":[92,8]}},"annotation":{"meta":null,"sourceSpan":{"end":[100,18],"start":[100,15]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[100,18],"start":[100,17]}},"kind":"Var","type":{"annotation":[{"end":[92,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,20]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"j","sourcePos":[99,16]}},"kind":"App"},"kind":"Let"},"identifier":"h"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[101,7],"start":[101,6]}},"kind":"Var","type":{"annotation":[{"end":[92,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[92,20]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"h","sourcePos":[98,8]}},"kind":"Let"},"identifier":"nestedBinds"},{"annotation":{"meta":null,"sourceSpan":{"end":[183,26],"start":[183,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsWhere"},"sourceSpan":{"end":[184,39],"start":[184,22]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[186,14],"start":[186,5]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[186,14],"start":[186,5]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[186,14],"start":[186,5]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[186,14],"start":[186,13]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"x","sourcePos":[186,5]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"i"},{"annotation":{"meta":null,"sourceSpan":{"end":[191,13],"start":[189,5]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[190,8],"start":[190,7]}},"binderType":"LiteralBinder","literal":{"literalType":"IntLiteral","value":2}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[190,13],"start":[190,12]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":3}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[191,8],"start":[191,7]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[191,13],"start":[191,12]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":5}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"v","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"h"},{"annotation":{"meta":null,"sourceSpan":{"end":[188,12],"start":[188,5]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[188,12],"start":[188,5]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[188,12],"start":[188,11]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":5}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"g"},{"annotation":{"meta":null,"sourceSpan":{"end":[187,12],"start":[187,5]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[187,12],"start":[187,5]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[187,12],"start":[187,11]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"x","sourcePos":[187,5]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"f"}],"expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[184,23],"start":[184,22]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"i","sourcePos":[186,5]}},"annotation":{"meta":null,"sourceSpan":{"end":[184,37],"start":[184,22]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[184,26],"start":[184,25]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"f","sourcePos":[187,5]}},"annotation":{"meta":null,"sourceSpan":{"end":[184,36],"start":[184,25]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[184,29],"start":[184,28]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"g","sourcePos":[188,5]}},"annotation":{"meta":null,"sourceSpan":{"end":[184,35],"start":[184,28]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[184,32],"start":[184,31]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"h","sourcePos":[189,5]}},"annotation":{"meta":null,"sourceSpan":{"end":[184,34],"start":[184,31]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[184,34],"start":[184,33]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"kind":"App"},"kind":"App"},"kind":"App"},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[184,39],"start":[184,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[184,39],"start":[184,38]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":4}},"kind":"App"},"kind":"Let"},"identifier":"nestedApplications"},{"annotation":{"meta":null,"sourceSpan":{"end":[83,44],"start":[83,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[88,10],"start":[85,3]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[86,17],"start":[86,7]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[86,17],"start":[86,7]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[86,17],"start":[86,7]}},"argument":"y","body":{"annotation":{"meta":null,"sourceSpan":{"end":[86,17],"start":[86,16]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"y","sourcePos":[86,7]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"h'"},{"annotation":{"meta":null,"sourceSpan":{"end":[87,25],"start":[87,7]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[87,25],"start":[87,7]}},"argument":"y","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[87,16],"start":[87,14]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"h'","sourcePos":[86,7]}},"annotation":{"meta":null,"sourceSpan":{"end":[87,23],"start":[87,14]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[87,20],"start":[87,18]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"f'","sourcePos":[85,7]}},"annotation":{"meta":null,"sourceSpan":{"end":[87,22],"start":[87,18]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[87,22],"start":[87,21]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"y","sourcePos":[87,7]}},"kind":"App"},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[87,25],"start":[87,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[87,25],"start":[87,24]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":3}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"g'"},{"annotation":{"meta":null,"sourceSpan":{"end":[85,18],"start":[85,7]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[85,18],"start":[85,7]}},"argument":"x","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[85,16],"start":[85,14]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"g'","sourcePos":[87,7]}},"annotation":{"meta":null,"sourceSpan":{"end":[85,18],"start":[85,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[85,18],"start":[85,17]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"f'"}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[88,8],"start":[88,6]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"g'","sourcePos":[87,7]}},"annotation":{"meta":null,"sourceSpan":{"end":[88,10],"start":[88,6]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[88,10],"start":[88,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":3}},"kind":"App"},"kind":"Let"},"identifier":"mutuallyRecursiveBindingGroupNoTypes"},{"annotation":{"meta":null,"sourceSpan":{"end":[72,37],"start":[72,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[80,9],"start":[74,3]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[76,29],"start":[76,7]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[77,16],"start":[77,7]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[77,16],"start":[77,7]}},"argument":"y","body":{"annotation":{"meta":null,"sourceSpan":{"end":[77,16],"start":[77,15]}},"kind":"Var","type":{"annotation":[{"end":[76,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,19]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"y","sourcePos":[77,7]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[76,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,19]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[76,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,26]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[76,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,12]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[76,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,19]},[]],"contents":[{"annotation":[{"end":[76,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,19]},[]],"contents":[{"annotation":[{"end":[76,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,23]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[76,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,19]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[76,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,26]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"h"},{"annotation":{"meta":null,"sourceSpan":{"end":[78,22],"start":[78,7]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[79,22],"start":[79,7]}},"argument":"y","body":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[79,14],"start":[79,13]}},"kind":"Var","type":{"annotation":[{"end":[76,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,12]},[]],"contents":[{"annotation":[{"end":[76,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,12]},[]],"contents":[{"annotation":[{"end":[76,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[76,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,12]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[76,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,19]},[]],"contents":[{"annotation":[{"end":[76,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,19]},[]],"contents":[{"annotation":[{"end":[76,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,23]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[76,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,19]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[76,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[76,26]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"h","sourcePos":[76,7]}},"annotation":{"meta":null,"sourceSpan":{"end":[79,20],"start":[79,13]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[79,17],"start":[79,16]}},"kind":"Var","type":{"annotation":[{"end":[74,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[74,12]},[]],"contents":[{"annotation":[{"end":[74,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[74,12]},[]],"contents":[{"annotation":[{"end":[74,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[74,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[74,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[74,12]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[74,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[74,19]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"f","sourcePos":[74,7]}},"annotation":{"meta":null,"sourceSpan":{"end":[79,19],"start":[79,16]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[79,19],"start":[79,18]}},"kind":"Var","type":{"annotation":[{"end":[78,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,12]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"y","sourcePos":[79,7]}},"kind":"App"},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[79,22],"start":[79,13]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[79,22],"start":[79,21]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":3}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[78,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,12]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[78,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,19]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"g"},{"annotation":{"meta":null,"sourceSpan":{"end":[74,22],"start":[74,7]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[75,16],"start":[75,7]}},"argument":"x","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[75,14],"start":[75,13]}},"kind":"Var","type":{"annotation":[{"end":[78,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,12]},[]],"contents":[{"annotation":[{"end":[78,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,12]},[]],"contents":[{"annotation":[{"end":[78,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[78,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,12]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[78,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,19]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"g","sourcePos":[78,7]}},"annotation":{"meta":null,"sourceSpan":{"end":[75,16],"start":[75,13]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[75,16],"start":[75,15]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[74,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[74,12]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[74,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[74,19]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"f"}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[80,7],"start":[80,6]}},"kind":"Var","type":{"annotation":[{"end":[78,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,12]},[]],"contents":[{"annotation":[{"end":[78,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,12]},[]],"contents":[{"annotation":[{"end":[78,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[78,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,12]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[78,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[78,19]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"g","sourcePos":[78,7]}},"annotation":{"meta":null,"sourceSpan":{"end":[80,9],"start":[80,6]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[80,9],"start":[80,8]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":3}},"kind":"App"},"kind":"Let"},"identifier":"mutuallyRecursiveBindingGroup"},{"annotation":{"meta":null,"sourceSpan":{"end":[8,27],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[9,15],"start":[9,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[9,15],"start":[9,1]}},"argument":"v1","body":{"annotation":{"meta":null,"sourceSpan":{"end":[9,15],"start":[9,13]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":42}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,17]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,10]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,17]},[]],"contents":[{"annotation":[{"end":[8,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,17]},[]],"contents":[{"annotation":[{"end":[8,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,17]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"minus"},{"annotation":{"meta":null,"sourceSpan":{"end":[173,16],"start":[173,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[173,12],"start":[173,8]}},"kind":"Var","type":{"annotation":[{"end":[168,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,9]},[]],"contents":[{"annotation":[{"end":[168,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,9]},[]],"contents":[{"annotation":[{"end":[168,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[168,12],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,9]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[168,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,16]},[]],"contents":[{"annotation":[{"end":[168,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,16]},[]],"contents":[{"annotation":[{"end":[168,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,20]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[168,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[168,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[168,23]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"plus","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[173,14],"start":[173,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[173,14],"start":[173,13]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[173,16],"start":[173,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[173,16],"start":[173,15]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"kind":"App"},"identifier":"main"},{"annotation":{"meta":null,"sourceSpan":{"end":[223,23],"start":[223,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[224,9],"start":[224,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[224,9],"start":[224,8]}},"kind":"Var","type":{"annotation":[{"end":[223,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,17]},[]],"contents":"t","tag":"TypeVar"},"value":{"identifier":"x","sourcePos":[224,1]}},"kind":"Abs","type":{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,7]},[]],"contents":{"identifier":"t","kind":{"annotation":[{"end":[223,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,19]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":19,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[223,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,17]},[]],"contents":"t","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,22]},[]],"contents":"t","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"id"},{"annotation":{"meta":null,"sourceSpan":{"end":[226,62],"start":[226,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[227,37],"start":[227,13]}},"kind":"Literal","type":{"annotation":[{"end":[226,62],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,14]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[226,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,39]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":22,"type":{"annotation":[{"end":[226,62],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,23]},[]],"contents":{"identifier":"b","kind":{"annotation":[{"end":[226,59],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,57]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":21,"type":{"annotation":[{"end":[226,62],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,26]},[]],"contents":[{"annotation":[{"end":[226,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,26]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[226,43],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,27]},[]],"contents":["getIdA",{"annotation":[{"end":[226,43],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,37]},[]],"contents":[{"annotation":[{"end":[226,43],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,37]},[]],"contents":[{"annotation":[{"end":[226,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,39]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[226,38],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,37]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[226,43],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,42]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[226,61],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,45]},[]],"contents":["getIdB",{"annotation":[{"end":[226,61],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,55]},[]],"contents":[{"annotation":[{"end":[226,61],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,55]},[]],"contents":[{"annotation":[{"end":[226,59],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,57]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[226,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,55]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[226,61],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,60]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[226,62],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,61]},[]],"contents":[{"annotation":[{"end":[226,62],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,61]},[]],"tag":"REmpty"},{"annotation":[{"end":[226,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[226,39]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"literalType":"ObjectLiteral","value":[["getIdB",{"annotation":{"meta":null,"sourceSpan":{"end":[227,36],"start":[227,34]}},"kind":"Var","type":{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,7]},[]],"contents":{"identifier":"t","kind":{"annotation":[{"end":[223,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,19]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":19,"type":{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,17]},[]],"contents":[{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,17]},[]],"contents":[{"annotation":[{"end":[223,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,19]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[223,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,17]},[]],"contents":"t","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,22]},[]],"contents":"t","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"id","moduleName":["Lib"]}}],["getIdA",{"annotation":{"meta":null,"sourceSpan":{"end":[227,24],"start":[227,22]}},"kind":"Var","type":{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,7]},[]],"contents":{"identifier":"t","kind":{"annotation":[{"end":[223,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,19]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":19,"type":{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,17]},[]],"contents":[{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,17]},[]],"contents":[{"annotation":[{"end":[223,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,19]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[223,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,17]},[]],"contents":"t","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,22]},[]],"contents":"t","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"id","moduleName":["Lib"]}}]]}},"identifier":"objForall"},{"annotation":{"meta":null,"sourceSpan":{"end":[30,27],"start":[30,3]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[30,27],"start":[30,3]}},"argument":"dict","body":{"annotation":{"meta":null,"sourceSpan":{"end":[30,27],"start":[30,3]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[30,27],"start":[30,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[30,27],"start":[30,3]}},"binderType":"VarBinder","identifier":"v"}],"constructorName":{"identifier":"Eq2$Dict","moduleName":["Lib"]},"typeName":{"identifier":"Eq2$Dict","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[30,27],"start":[30,3]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[30,27],"start":[30,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq2",{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"v","sourcePos":[30,3]}},"fieldName":"eq2","kind":"Accessor","type":{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[30,27],"start":[30,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq2$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"dict","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":26,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"b","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":25,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq2$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"visibility":"TypeVarVisible"},"tag":"ForAll"}},"identifier":"eq2"},{"annotation":{"meta":null,"sourceSpan":{"end":[35,19],"start":[35,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[36,14],"start":[36,11]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":26,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"b","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":25,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq2$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":[{"annotation":[{"end":[30,14],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,12]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":[{"annotation":[{"end":[30,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,17]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[30,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,15]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[30,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[30,20]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"eq2","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[36,18],"start":[36,11]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq2$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[32,17],"name":"tests/purus/passing/Misc/Lib.purs","start":[32,14]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[32,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[32,18]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"eq2IntBoolean","moduleName":["Lib"]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[36,18],"start":[36,11]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[36,18],"start":[36,15]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":101}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[36,24],"start":[36,11]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[36,24],"start":[36,19]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"literalType":"BooleanLiteral","value":false}},"kind":"App"},"identifier":"testEq2"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,26],"start":[6,3]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,26],"start":[6,3]}},"argument":"dict","body":{"annotation":{"meta":null,"sourceSpan":{"end":[6,26],"start":[6,3]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[6,26],"start":[6,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,26],"start":[6,3]}},"binderType":"VarBinder","identifier":"v"}],"constructorName":{"identifier":"Eq$Dict","moduleName":["Lib"]},"typeName":{"identifier":"Eq$Dict","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,26],"start":[6,3]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,26],"start":[6,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["eq",{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"v","sourcePos":[6,3]}},"fieldName":"eq","kind":"Accessor","type":{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,26],"start":[6,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"dict","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":27,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"}},"identifier":"eq"},{"annotation":{"meta":null,"sourceSpan":{"end":[14,18],"start":[14,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[15,12],"start":[15,10]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":27,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"eq","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[15,14],"start":[15,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"eqInt","moduleName":["Lib"]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[15,14],"start":[15,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[15,14],"start":[15,13]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[15,16],"start":[15,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[15,16],"start":[15,15]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"kind":"App"},"identifier":"testEq"},{"annotation":{"meta":null,"sourceSpan":{"end":[255,53],"start":[255,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"dictOrd","body":{"annotation":{"meta":null,"sourceSpan":{"end":[256,26],"start":[256,1]}},"argument":"a","body":{"annotation":{"meta":null,"sourceSpan":{"end":[256,26],"start":[256,1]}},"argument":"b","body":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[256,22],"start":[256,20]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":27,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"eq","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[256,24],"start":[256,20]}},"argument":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[256,24],"start":[256,20]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Ord$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[255,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,31]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"dictOrd","sourcePos":[0,0]}},"fieldName":"Eq0","kind":"Accessor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[249,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[249,10]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"annotation":{"meta":null,"sourceSpan":{"end":[256,24],"start":[256,20]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[256,24],"start":[256,20]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[]}},"kind":"App"},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[256,24],"start":[256,20]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[256,24],"start":[256,23]}},"kind":"Var","type":{"annotation":[{"end":[255,37],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,36]},[]],"contents":"a","tag":"TypeVar"},"value":{"identifier":"a","sourcePos":[256,1]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[256,26],"start":[256,20]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[256,26],"start":[256,25]}},"kind":"Var","type":{"annotation":[{"end":[255,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,41]},[]],"contents":"a","tag":"TypeVar"},"value":{"identifier":"b","sourcePos":[256,1]}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[255,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,41]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[255,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,46]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[255,37],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,36]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[255,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,41]},[]],"contents":[{"annotation":[{"end":[255,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,41]},[]],"contents":[{"annotation":[{"end":[255,45],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,43]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[255,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,41]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[255,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,46]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[255,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,17]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[255,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,27]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":28,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Ord$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[255,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,31]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[255,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,36]},[]],"contents":[{"annotation":[{"end":[255,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,36]},[]],"contents":[{"annotation":[{"end":[255,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,38]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[255,37],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,36]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[255,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,41]},[]],"contents":[{"annotation":[{"end":[255,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,41]},[]],"contents":[{"annotation":[{"end":[255,45],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,43]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[255,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,41]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[255,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[255,46]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"testEqViaOrd"},{"annotation":{"meta":null,"sourceSpan":{"end":[18,26],"start":[18,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[21,12],"start":[19,1]}},"argument":"n","body":{"annotation":{"meta":null,"sourceSpan":{"end":[21,12],"start":[20,5]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[21,12],"start":[20,5]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[20,23],"start":[20,22]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[21,12],"start":[20,5]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[21,12],"start":[21,10]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":42}},"isGuarded":false}],"caseExpressions":[{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[20,13],"start":[20,11]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":27,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"eq","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[20,16],"start":[20,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"eqInt","moduleName":["Lib"]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[20,16],"start":[20,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[20,9],"start":[20,8]}},"kind":"Var","type":{"annotation":[{"end":[18,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[18,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"n","sourcePos":[19,1]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[20,16],"start":[20,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[20,16],"start":[20,15]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":0}},"kind":"App"}],"kind":"Case","type":{"annotation":[{"end":[18,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[18,23]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[18,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[18,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[18,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[18,23]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"workingEven"},{"annotation":{"meta":null,"sourceSpan":{"end":[217,15],"start":[217,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[217,15],"start":[217,13]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"t121","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"t121","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"literalType":"ArrayLiteral","value":[]}},"identifier":"emptyList"},{"annotation":{"meta":null,"sourceSpan":{"end":[214,42],"start":[214,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[215,16],"start":[215,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[215,16],"start":[215,1]}},"argument":"xs","body":{"annotation":{"meta":null,"sourceSpan":{"end":[215,16],"start":[215,13]}},"kind":"Literal","type":{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,35]},[]],"contents":[{"annotation":[{"end":[214,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,35]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,41]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"literalType":"ArrayLiteral","value":[{"annotation":{"meta":null,"sourceSpan":{"end":[215,15],"start":[215,14]}},"kind":"Var","type":{"annotation":[{"end":[214,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,19]},[]],"contents":"a","tag":"TypeVar"},"value":{"identifier":"x","sourcePos":[215,1]}}]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[{"annotation":[{"end":[214,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,30]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,35]},[]],"contents":[{"annotation":[{"end":[214,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,35]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,41]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,9]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[214,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,21]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":30,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,19]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[{"annotation":[{"end":[214,34],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,32]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[{"annotation":[{"end":[214,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,30]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,35]},[]],"contents":[{"annotation":[{"end":[214,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,35]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,41]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"cons"},{"annotation":{"meta":null,"sourceSpan":{"end":[219,34],"start":[219,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[219,22],"start":[219,18]}},"kind":"Var","type":{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,9]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[214,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,21]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":30,"type":{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,19]},[]],"contents":[{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,19]},[]],"contents":[{"annotation":[{"end":[214,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,19]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[{"annotation":[{"end":[214,34],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,32]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[{"annotation":[{"end":[214,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,30]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,35]},[]],"contents":[{"annotation":[{"end":[214,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,35]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,41]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"cons","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[219,24],"start":[219,18]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[219,24],"start":[219,23]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[219,34],"start":[219,18]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[219,34],"start":[219,25]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"t121","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"t121","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"emptyList","moduleName":["Lib"]}},"kind":"App"},"identifier":"consEmptyList1"},{"annotation":{"meta":null,"sourceSpan":{"end":[221,40],"start":[221,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[221,22],"start":[221,18]}},"kind":"Var","type":{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,9]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[214,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,21]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":30,"type":{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,19]},[]],"contents":[{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,19]},[]],"contents":[{"annotation":[{"end":[214,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,19]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[{"annotation":[{"end":[214,34],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,32]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[{"annotation":[{"end":[214,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,24]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,30]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,35]},[]],"contents":[{"annotation":[{"end":[214,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,35]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[214,42],"name":"tests/purus/passing/Misc/Lib.purs","start":[214,41]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"cons","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[221,30],"start":[221,18]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[221,30],"start":[221,23]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"hello"}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[221,40],"start":[221,18]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[221,40],"start":[221,31]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"t121","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"t121","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"emptyList","moduleName":["Lib"]}},"kind":"App"},"identifier":"consEmptyList2"},{"annotation":{"meta":null,"sourceSpan":{"end":[250,27],"start":[250,3]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[250,27],"start":[250,3]}},"argument":"dict","body":{"annotation":{"meta":null,"sourceSpan":{"end":[250,27],"start":[250,3]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[250,27],"start":[250,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[250,27],"start":[250,3]}},"binderType":"VarBinder","identifier":"v"}],"constructorName":{"identifier":"Ord$Dict","moduleName":["Lib"]},"typeName":{"identifier":"Ord$Dict","moduleName":["Lib"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[250,27],"start":[250,3]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[250,27],"start":[250,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["compare",{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["Eq0",{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"v","sourcePos":[250,3]}},"fieldName":"compare","kind":"Accessor","type":{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[250,27],"start":[250,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Ord$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"dict","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":34,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Ord$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":[{"annotation":[{"end":[250,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":[{"annotation":[{"end":[250,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[250,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,19]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[250,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[250,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"}},"identifier":"compare"},{"bindType":"Rec","binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[23,25],"start":[23,1]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[26,34],"start":[24,1]}},"argument":"n","body":{"annotation":{"meta":null,"sourceSpan":{"end":[26,34],"start":[25,5]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[26,34],"start":[25,5]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[25,23],"start":[25,22]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[26,34],"start":[25,5]}},"binderType":"NullBinder"}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[26,20],"start":[26,10]}},"kind":"Var","type":{"annotation":[{"end":[23,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[23,15]},[]],"contents":[{"annotation":[{"end":[23,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[23,15]},[]],"contents":[{"annotation":[{"end":[23,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[23,19]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[23,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[23,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[23,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[23,22]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"brokenEven","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[26,34],"start":[26,10]}},"argument":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[26,30],"start":[26,25]}},"kind":"Var","type":{"annotation":[{"end":[8,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,10]},[]],"contents":[{"annotation":[{"end":[8,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,10]},[]],"contents":[{"annotation":[{"end":[8,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,14]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,10]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,17]},[]],"contents":[{"annotation":[{"end":[8,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,17]},[]],"contents":[{"annotation":[{"end":[8,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,21]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,20],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,17]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[8,24]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"minus","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[26,23],"start":[26,22]}},"kind":"Var","type":{"annotation":[{"end":[23,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[23,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"n","sourcePos":[24,1]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,22]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[26,33],"start":[26,32]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"kind":"App"},"kind":"App"},"isGuarded":false}],"caseExpressions":[{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[25,13],"start":[25,11]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":27,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"eq","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[25,16],"start":[25,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"eqInt","moduleName":["Lib"]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[25,16],"start":[25,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[25,9],"start":[25,8]}},"kind":"Var","type":{"annotation":[{"end":[23,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[23,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"n","sourcePos":[24,1]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[25,16],"start":[25,8]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[25,16],"start":[25,15]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":0}},"kind":"App"}],"kind":"Case","type":{"annotation":[{"end":[23,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[23,22]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[23,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[23,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[23,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[23,22]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"brokenEven"}]},{"annotation":{"meta":null,"sourceSpan":{"end":[229,38],"start":[229,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[230,17],"start":[230,13]}},"kind":"Literal","type":{"annotation":[{"end":[229,38],"name":"tests/purus/passing/Misc/Lib.purs","start":[229,14]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[229,35],"name":"tests/purus/passing/Misc/Lib.purs","start":[229,33]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":35,"type":{"annotation":[{"end":[229,38],"name":"tests/purus/passing/Misc/Lib.purs","start":[229,24]},[]],"contents":[{"annotation":[{"end":[229,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[229,24]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[229,37],"name":"tests/purus/passing/Misc/Lib.purs","start":[229,31]},[]],"contents":[{"annotation":[{"end":[229,37],"name":"tests/purus/passing/Misc/Lib.purs","start":[229,31]},[]],"contents":[{"annotation":[{"end":[229,35],"name":"tests/purus/passing/Misc/Lib.purs","start":[229,33]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[229,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[229,31]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[229,37],"name":"tests/purus/passing/Misc/Lib.purs","start":[229,36]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"literalType":"ArrayLiteral","value":[{"annotation":{"meta":null,"sourceSpan":{"end":[230,16],"start":[230,14]}},"kind":"Var","type":{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,7]},[]],"contents":{"identifier":"t","kind":{"annotation":[{"end":[223,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,19]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":19,"type":{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,17]},[]],"contents":[{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,17]},[]],"contents":[{"annotation":[{"end":[223,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,19]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[223,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,17]},[]],"contents":"t","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[223,23],"name":"tests/purus/passing/Misc/Lib.purs","start":[223,22]},[]],"contents":"t","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"id","moduleName":["Lib"]}}]}},"identifier":"arrForall"},{"annotation":{"meta":null,"sourceSpan":{"end":[195,22],"start":[195,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[196,17],"start":[196,9]}},"kind":"Literal","type":{"annotation":[{"end":[195,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,10]},[]],"contents":[{"annotation":[{"end":[195,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,10]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[195,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,11]},[]],"contents":["foo",{"annotation":[{"end":[195,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,18]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[195,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,21]},[]],"contents":[{"annotation":[{"end":[195,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,21]},[]],"tag":"REmpty"},{"annotation":[{"end":[195,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,18]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[["foo",{"annotation":{"meta":null,"sourceSpan":{"end":[196,16],"start":[196,15]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":3}}]]}},"identifier":"anObj"},{"annotation":{"meta":null,"sourceSpan":{"end":[198,26],"start":[198,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[199,28],"start":[199,13]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[199,28],"start":[199,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[199,18],"start":[199,13]}},"kind":"Var","type":{"annotation":[{"end":[195,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,10]},[]],"contents":[{"annotation":[{"end":[195,11],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,10]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[195,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,11]},[]],"contents":["foo",{"annotation":[{"end":[195,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,18]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[195,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,21]},[]],"contents":[{"annotation":[{"end":[195,22],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,21]},[]],"tag":"REmpty"},{"annotation":[{"end":[195,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,18]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"anObj","moduleName":["Lib"]}},"identifier":"v"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[199,28],"start":[199,13]}},"copy":[],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["foo",{"annotation":[{"end":[195,21],"name":"tests/purus/passing/Misc/Lib.purs","start":[195,18]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[198,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[198,25]},[]],"contents":[{"annotation":[{"end":[198,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[198,25]},[]],"tag":"REmpty"},{"annotation":[{"end":[198,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[198,22]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"v","sourcePos":[199,1]}},"kind":"ObjectUpdate","type":{"annotation":[{"end":[198,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[198,14]},[]],"contents":[{"annotation":[{"end":[198,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[198,14]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[198,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[198,15]},[]],"contents":["foo",{"annotation":[{"end":[198,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[198,22]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[198,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[198,25]},[]],"contents":[{"annotation":[{"end":[198,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[198,25]},[]],"tag":"REmpty"},{"annotation":[{"end":[198,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[198,22]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"updates":[["foo",{"annotation":{"meta":null,"sourceSpan":{"end":[199,27],"start":[199,26]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":4}}]]},"kind":"Let"},"identifier":"objUpdate"},{"annotation":{"meta":null,"sourceSpan":{"end":[111,16],"start":[111,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[112,13],"start":[112,12]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"identifier":"anIntLit"},{"annotation":{"meta":null,"sourceSpan":{"end":[117,12],"start":[117,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[118,9],"start":[118,8]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"identifier":"aVal"},{"annotation":{"meta":null,"sourceSpan":{"end":[114,21],"start":[114,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[115,20],"start":[115,14]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"woop"}},"identifier":"aStringLit"},{"annotation":{"meta":null,"sourceSpan":{"end":[211,24],"start":[211,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[212,15],"start":[212,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[212,15],"start":[212,11]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"literalType":"BooleanLiteral","value":true}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[211,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[211,10]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[211,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[211,17]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"aPred"},{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,1]}},"argument":"w","body":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"argument":"v1","body":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[181,11]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":0}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"$23","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,1]},[]],"contents":"$23","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,30]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"v"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[177,4],"start":[177,3]}},"binderType":"VarBinder","identifier":"y"},{"annotation":{"meta":null,"sourceSpan":{"end":[177,7],"start":[177,6]}},"binderType":"VarBinder","identifier":"z"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[177,12],"start":[177,10]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":27,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"eq","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[177,14],"start":[177,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"eqInt","moduleName":["Lib"]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[177,14],"start":[177,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[177,14],"start":[177,13]}},"kind":"Var","type":{"annotation":[{"end":[175,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"y","sourcePos":[177,3]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[177,16],"start":[177,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[177,16],"start":[177,15]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"kind":"App"},"identifier":"v1"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[178,15],"start":[178,10]}},"kind":"Var","type":{"annotation":[{"end":[211,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[211,10]},[]],"contents":[{"annotation":[{"end":[211,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[211,10]},[]],"contents":[{"annotation":[{"end":[211,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[211,14]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[211,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[211,10]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[211,24],"name":"tests/purus/passing/Misc/Lib.purs","start":[211,17]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"aPred","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[178,17],"start":[178,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[178,17],"start":[178,16]}},"kind":"Var","type":{"annotation":[{"end":[175,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"y","sourcePos":[177,3]}},"kind":"App"},"identifier":"v2"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[179,12],"start":[179,10]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":27,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"eq","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[179,14],"start":[179,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"eqInt","moduleName":["Lib"]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[179,14],"start":[179,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[179,14],"start":[179,13]}},"kind":"Var","type":{"annotation":[{"end":[175,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,23]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"z","sourcePos":[177,6]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[179,16],"start":[179,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[179,16],"start":[179,15]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":0}},"kind":"App"},"identifier":"v3"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[180,12],"start":[180,10]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":27,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"eq","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[180,14],"start":[180,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"eqInt","moduleName":["Lib"]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[180,14],"start":[180,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[180,14],"start":[180,13]}},"kind":"Var","type":{"annotation":[{"end":[175,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"y","sourcePos":[177,3]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[180,26],"start":[180,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[180,26],"start":[180,15]}},"kind":"Var","type":{"annotation":[{"end":[90,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[90,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"nestedBinds","moduleName":["Lib"]}},"kind":"App"},"identifier":"v4"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[180,31],"start":[180,30]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"binderType":"NullBinder"}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"$23","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,1]},[]],"contents":"$23","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,30]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"v","sourcePos":[0,0]}},"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"literalType":"BooleanLiteral","value":true}},"kind":"App"},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"identifier":"v4","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Let"},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"binderType":"NullBinder"}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"$23","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,1]},[]],"contents":"$23","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,30]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"v","sourcePos":[0,0]}},"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"literalType":"BooleanLiteral","value":true}},"kind":"App"},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"identifier":"v3","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Let"},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"binderType":"NullBinder"}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"$23","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,1]},[]],"contents":"$23","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,30]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"v","sourcePos":[0,0]}},"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"literalType":"BooleanLiteral","value":true}},"kind":"App"},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"identifier":"v2","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Let"},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"binderType":"NullBinder"}],"expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"$23","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,1]},[]],"contents":"$23","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,30]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"v","sourcePos":[0,0]}},"annotation":{"meta":null,"sourceSpan":{"end":[181,12],"start":[176,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"literalType":"BooleanLiteral","value":true}},"kind":"App"},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[175,33],"start":[175,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"identifier":"v1","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Let"},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[176,25],"start":[176,24]}},"kind":"Var","type":{"annotation":[{"end":[175,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"w","sourcePos":[176,1]}},{"annotation":{"meta":null,"sourceSpan":{"end":[176,28],"start":[176,27]}},"kind":"Var","type":{"annotation":[{"end":[175,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,23]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"x","sourcePos":[176,1]}}],"kind":"Case","type":{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,30]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Let"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[175,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,23]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,30]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[175,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,23]},[]],"contents":[{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,23]},[]],"contents":[{"annotation":[{"end":[175,29],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,27]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[175,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,23]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[175,33],"name":"tests/purus/passing/Misc/Lib.purs","start":[175,30]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"guardedCase"},{"annotation":{"meta":null,"sourceSpan":{"end":[129,19],"start":[129,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[130,20],"start":[130,9]}},"kind":"Literal","type":{"annotation":[{"end":[129,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[129,10]},[]],"contents":[{"annotation":[{"end":[129,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[129,10]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[129,19],"name":"tests/purus/passing/Misc/Lib.purs","start":[129,16]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"literalType":"ArrayLiteral","value":[{"annotation":{"meta":null,"sourceSpan":{"end":[130,11],"start":[130,10]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},{"annotation":{"meta":null,"sourceSpan":{"end":[130,13],"start":[130,12]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},{"annotation":{"meta":null,"sourceSpan":{"end":[130,15],"start":[130,14]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":3}},{"annotation":{"meta":null,"sourceSpan":{"end":[130,17],"start":[130,16]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":4}},{"annotation":{"meta":null,"sourceSpan":{"end":[130,19],"start":[130,18]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":5}}]}},"identifier":"aList"},{"annotation":{"meta":null,"sourceSpan":{"end":[143,60],"start":[143,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[144,19],"start":[144,1]}},"argument":"r","body":{"annotation":{"meta":null,"sourceSpan":{"end":[144,19],"start":[144,16]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[144,17],"start":[144,16]}},"kind":"Var","type":{"annotation":[{"end":[143,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,39]},[]],"contents":[{"annotation":[{"end":[143,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,39]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[143,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,40]},[]],"contents":["a",{"annotation":[{"end":[143,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,45]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[143,52],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,51]},[]],"contents":"r","tag":"TypeVar"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"r","sourcePos":[144,1]}},"fieldName":"a","kind":"Accessor","type":{"annotation":[{"end":[143,60],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,57]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Abs","type":{"annotation":[{"end":[143,60],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,15]},[]],"contents":{"identifier":"r","kind":{"annotation":[{"end":[143,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,28]},[]],"contents":[{"annotation":[{"end":[143,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,28]},[]],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[{"end":[143,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,32]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"skolem":37,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[143,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,39]},[]],"contents":[{"annotation":[{"end":[143,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,39]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[143,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,40]},[]],"contents":["a",{"annotation":[{"end":[143,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,45]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[143,52],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,51]},[]],"contents":"r","tag":"TypeVar"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[143,60],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,57]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"aFunction4"},{"annotation":{"meta":null,"sourceSpan":{"end":[146,18],"start":[146,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[147,24],"start":[147,14]}},"kind":"Var","type":{"annotation":[{"end":[143,60],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,15]},[]],"contents":{"identifier":"r","kind":{"annotation":[{"end":[143,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,28]},[]],"contents":[{"annotation":[{"end":[143,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,28]},[]],"contents":[["Prim"],"Row"],"tag":"TypeConstructor"},{"annotation":[{"end":[143,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,32]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"skolem":37,"type":{"annotation":[{"end":[143,60],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,39]},[]],"contents":[{"annotation":[{"end":[143,60],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,39]},[]],"contents":[{"annotation":[{"end":[143,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,54]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[143,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,39]},[]],"contents":[{"annotation":[{"end":[143,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,39]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[143,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,40]},[]],"contents":["a",{"annotation":[{"end":[143,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,45]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[143,52],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,51]},[]],"contents":"r","tag":"TypeVar"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[143,60],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,57]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"aFunction4","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[147,31],"start":[147,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[147,31],"start":[147,25]}},"kind":"Literal","type":{"annotation":[{"end":[143,53],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,39]},[]],"contents":[{"annotation":[{"end":[143,40],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,39]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[143,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,40]},[]],"contents":["a",{"annotation":[{"end":[143,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,45]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[143,36],"name":"tests/purus/passing/Misc/Lib.purs","start":[143,32]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[["a",{"annotation":{"meta":null,"sourceSpan":{"end":[147,30],"start":[147,29]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}}]]}},"kind":"App"},"identifier":"aFunction5"},{"annotation":{"meta":null,"sourceSpan":{"end":[140,25],"start":[140,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[141,41],"start":[141,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[141,41],"start":[141,16]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[141,41],"start":[141,16]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[141,34],"start":[141,33]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":4}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[141,41],"start":[141,16]}},"binderType":"NullBinder"}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[141,41],"start":[141,40]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"isGuarded":false}],"caseExpressions":[{"abstraction":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[141,22],"start":[141,20]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":27,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":[{"annotation":[{"end":[6,13],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,10],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,9]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":[{"annotation":[{"end":[6,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,16]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,14]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,26],"name":"tests/purus/passing/Misc/Lib.purs","start":[6,19]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"eq","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[141,24],"start":[141,20]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Lib"],"Eq$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[11,16],"name":"tests/purus/passing/Misc/Lib.purs","start":[11,13]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"eqInt","moduleName":["Lib"]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[141,24],"start":[141,20]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[141,24],"start":[141,23]}},"kind":"Var","type":{"annotation":[{"end":[140,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[140,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"x","sourcePos":[141,1]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[141,26],"start":[141,20]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[141,26],"start":[141,25]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"kind":"App"}],"kind":"Case","type":{"annotation":[{"end":[140,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[140,22]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[140,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[140,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[140,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[140,22]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"aFunction3"},{"annotation":{"meta":null,"sourceSpan":{"end":[137,31],"start":[137,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[138,21],"start":[138,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[138,21],"start":[138,16]}},"kind":"Literal","type":{"annotation":[{"end":[137,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[137,22]},[]],"contents":[{"annotation":[{"end":[137,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[137,22]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[137,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[137,28]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"literalType":"ArrayLiteral","value":[{"annotation":{"meta":null,"sourceSpan":{"end":[138,18],"start":[138,17]}},"kind":"Var","type":{"annotation":[{"end":[137,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[137,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"x","sourcePos":[138,1]}},{"annotation":{"meta":null,"sourceSpan":{"end":[138,20],"start":[138,19]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}}]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[137,18],"name":"tests/purus/passing/Misc/Lib.purs","start":[137,15]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[137,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[137,22]},[]],"contents":[{"annotation":[{"end":[137,27],"name":"tests/purus/passing/Misc/Lib.purs","start":[137,22]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[137,31],"name":"tests/purus/passing/Misc/Lib.purs","start":[137,28]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"aFunction2"},{"annotation":{"meta":null,"sourceSpan":{"end":[134,56],"start":[134,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[135,24],"start":[135,1]}},"argument":"any","body":{"annotation":{"meta":null,"sourceSpan":{"end":[135,24],"start":[135,1]}},"argument":"f","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[135,20],"start":[135,19]}},"kind":"Var","type":{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,30]},[]],"contents":{"identifier":"y","kind":{"annotation":[{"end":[134,44],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,42]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":39,"type":{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":[{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":[{"annotation":[{"end":[134,44],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,42]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[134,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":"y","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,45]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"f","sourcePos":[135,1]}},"annotation":{"meta":null,"sourceSpan":{"end":[135,24],"start":[135,19]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[135,24],"start":[135,21]}},"kind":"Var","type":{"annotation":[{"end":[134,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,24]},[]],"contents":"x","tag":"TypeVar"},"value":{"identifier":"any","sourcePos":[135,1]}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,30]},[]],"contents":{"identifier":"y","kind":{"annotation":[{"end":[134,44],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,42]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":39,"type":{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":[{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":[{"annotation":[{"end":[134,44],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,42]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[134,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":"y","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,45]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}],"tag":"TypeApp"},{"annotation":[{"end":[134,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,53]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[134,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,14]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[134,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,26]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":40,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[134,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,24]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[134,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,29]},[]],"contents":[{"annotation":[{"end":[134,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,29]},[]],"contents":[{"annotation":[{"end":[134,52],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,50]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,30]},[]],"contents":{"identifier":"y","kind":{"annotation":[{"end":[134,44],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,42]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":39,"type":{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":[{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":[{"annotation":[{"end":[134,44],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,42]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[134,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":"y","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,45]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}],"tag":"TypeApp"},{"annotation":[{"end":[134,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,53]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"aFunction"},{"annotation":{"meta":null,"sourceSpan":{"end":[149,18],"start":[149,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsWhere"},"sourceSpan":{"end":[150,29],"start":[150,14]}},"binds":[{"annotation":{"meta":null,"sourceSpan":{"end":[152,39],"start":[152,5]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[153,14],"start":[153,5]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[153,14],"start":[153,12]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":10}},"kind":"Abs","type":{"annotation":[{"end":[152,39],"name":"tests/purus/passing/Misc/Lib.purs","start":[152,11]},[]],"contents":{"identifier":"z","kind":{"annotation":[{"end":[152,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[152,24]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":43,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[152,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[152,31]},[]],"contents":"z","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[152,39],"name":"tests/purus/passing/Misc/Lib.purs","start":[152,36]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"go"}],"expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[150,23],"start":[150,14]}},"kind":"Var","type":{"annotation":[{"end":[134,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,14]},[]],"contents":{"identifier":"x","kind":{"annotation":[{"end":[134,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,26]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":40,"type":{"annotation":[{"end":[134,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,24]},[]],"contents":[{"annotation":[{"end":[134,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,24]},[]],"contents":[{"annotation":[{"end":[134,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,26]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[134,25],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,24]},[]],"contents":"x","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[134,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,29]},[]],"contents":[{"annotation":[{"end":[134,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,29]},[]],"contents":[{"annotation":[{"end":[134,52],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,50]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,30]},[]],"contents":{"identifier":"y","kind":{"annotation":[{"end":[134,44],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,42]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":39,"type":{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":[{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":[{"annotation":[{"end":[134,44],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,42]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[134,41],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,40]},[]],"contents":"y","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[134,48],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,45]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}],"tag":"TypeApp"},{"annotation":[{"end":[134,56],"name":"tests/purus/passing/Misc/Lib.purs","start":[134,53]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"aFunction","moduleName":["Lib"]}},"annotation":{"meta":null,"sourceSpan":{"end":[150,26],"start":[150,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[150,26],"start":[150,24]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Array"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":151,"tag":"TUnknown"}],"tag":"TypeApp"},"value":{"literalType":"ArrayLiteral","value":[]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[150,29],"start":[150,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[150,29],"start":[150,27]}},"kind":"Var","type":{"annotation":[{"end":[152,39],"name":"tests/purus/passing/Misc/Lib.purs","start":[152,11]},[]],"contents":{"identifier":"z","kind":{"annotation":[{"end":[152,28],"name":"tests/purus/passing/Misc/Lib.purs","start":[152,24]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":43,"type":{"annotation":[{"end":[152,39],"name":"tests/purus/passing/Misc/Lib.purs","start":[152,31]},[]],"contents":[{"annotation":[{"end":[152,39],"name":"tests/purus/passing/Misc/Lib.purs","start":[152,31]},[]],"contents":[{"annotation":[{"end":[152,35],"name":"tests/purus/passing/Misc/Lib.purs","start":[152,33]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[152,32],"name":"tests/purus/passing/Misc/Lib.purs","start":[152,31]},[]],"contents":"z","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[152,39],"name":"tests/purus/passing/Misc/Lib.purs","start":[152,36]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"go","sourcePos":[152,5]}},"kind":"App"},"kind":"Let"},"identifier":"aFunction6"},{"annotation":{"meta":null,"sourceSpan":{"end":[126,17],"start":[126,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[127,13],"start":[127,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"literalType":"BooleanLiteral","value":true}},"identifier":"aBool"}],"exports":["compare","eq","eq2","minus","testEq","workingEven","brokenEven","testEq2","ConInt","ConInts","ConBoolean","ConString","ConChar","ConNested","ConQuantified","ConConstrained","ConObject","ConObjectQuantified","testBinders","mutuallyRecursiveBindingGroup","mutuallyRecursiveBindingGroupNoTypes","nestedBinds","ADataRec","ANewTypeRec","Constr1","Constr2","anIntLit","aStringLit","aVal","testasum","aBool","aList","aFunction","aFunction2","aFunction3","aFunction4","aFunction5","aFunction6","recF1","recG1","testBuiltin","plus","main","guardedCase","nestedApplications","anObj","objUpdate","polyInObj","polyInObjMatch","aPred","cons","emptyList","consEmptyList1","consEmptyList2","id","objForall","arrForall","testEqViaOrd","eqInt","eq2IntBoolean","ordInt"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[256,26],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[256,26],"start":[1,1]}},"moduleName":["Lib"]},{"annotation":{"meta":null,"sourceSpan":{"end":[256,26],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Lib"],"modulePath":"tests/purus/passing/Misc/Lib.purs","reExports":{},"sourceSpan":{"end":[256,26],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/Misc/output/Lib/index.cfn.pretty b/tests/purus/passing/Misc/output/Lib/index.cfn.pretty new file mode 100644 index 000000000..640ca2208 --- /dev/null +++ b/tests/purus/passing/Misc/output/Lib/index.cfn.pretty @@ -0,0 +1,484 @@ +Lib (tests/purus/passing/Misc/Lib.purs) +Imported Modules: + Builtin, + Lib, + Prim +Exports: + compare, + eq, + eq2, + minus, + testEq, + workingEven, + brokenEven, + testEq2, + ConInt, + ConInts, + ConBoolean, + ConString, + ConChar, + ConNested, + ConQuantified, + ConConstrained, + ConObject, + ConObjectQuantified, + testBinders, + mutuallyRecursiveBindingGroup, + mutuallyRecursiveBindingGroupNoTypes, + nestedBinds, + ADataRec, + ANewTypeRec, + Constr1, + Constr2, + anIntLit, + aStringLit, + aVal, + testasum, + aBool, + aList, + aFunction, + aFunction2, + aFunction3, + aFunction4, + aFunction5, + aFunction6, + recF1, + recG1, + testBuiltin, + plus, + main, + guardedCase, + nestedApplications, + anObj, + objUpdate, + polyInObj, + polyInObjMatch, + aPred, + cons, + emptyList, + consEmptyList1, + consEmptyList2, + id, + objForall, + arrForall, + testEqViaOrd, + eqInt, + eq2IntBoolean, + ordInt +Re-Exports: + +Foreign: + +Declarations: +Eq2$Dict :: forall a b. { eq2 :: a -> b -> Boolean } -> { eq2 :: a -> b -> Boolean } +Eq2$Dict = + \(x: { eq2 :: a -> b -> Boolean }) -> (x: { eq2 :: a -> b -> Boolean }) + +Eq$Dict :: forall a. { eq :: a -> a -> Boolean } -> { eq :: a -> a -> Boolean } +Eq$Dict = \(x: { eq :: a -> a -> Boolean }) -> (x: { eq :: a -> a -> Boolean }) + +Ord$Dict :: forall a. { compare :: a -> a -> Int, Eq0 :: Record {} -> Eq$Dict a } -> { compare :: a -> a -> Int, Eq0 :: Record {} -> Eq$Dict a } +Ord$Dict = + \(x: { compare :: a -> a -> Int, Eq0 :: Record {} -> Eq$Dict a }) -> + (x: { compare :: a -> a -> Int, Eq0 :: Record {} -> Eq$Dict a }) + +ConInt :: Int -> TestBinderSum +ConInt = ConInt + +ConInts :: Array (Int) -> TestBinderSum +ConInts = ConInts + +ConBoolean :: Boolean -> TestBinderSum +ConBoolean = ConBoolean + +ConString :: String -> TestBinderSum +ConString = ConString + +ConChar :: Char -> TestBinderSum +ConChar = ConChar + +ConNested :: TestBinderSum -> TestBinderSum +ConNested = ConNested + +ConQuantified :: forall (x :: Type). x -> Int -> TestBinderSum +ConQuantified = ConQuantified + +ConConstrained :: forall (x :: Type). Eq$Dict x -> x -> Int -> TestBinderSum +ConConstrained = ConConstrained + +ConObject :: { objField :: Int } -> TestBinderSum +ConObject = ConObject + +ConObjectQuantified :: { objFieldQ :: forall (x :: Type). x -> Int } -> TestBinderSum +ConObjectQuantified = ConObjectQuantified + +Constr1 :: Int -> ASum +Constr1 = Constr1 + +Constr2 :: Boolean -> ASum +Constr2 = Constr2 + +ANewTypeRec :: { foo :: Int } -> { foo :: Int } +ANewTypeRec = \(x: { foo :: Int }) -> (x: { foo :: Int }) + +ADataRec :: { hello :: Int, world :: Boolean } -> ADataRec +ADataRec = ADataRec + +eqInt :: Eq$Dict Int +eqInt = + (Eq$Dict: { eq :: Int -> Int -> Boolean } -> Eq$Dict Int) + ({ eq: \(v: Int) -> \(v1: Int) -> (true: Boolean) }: { + eq :: Int -> + Int -> Boolean + }) + +ordInt :: Ord$Dict Int +ordInt = + (Ord$Dict: { + compare :: Int -> Int -> Int, + Eq0 :: Record {}@Type -> Eq$Dict Int + } -> + Ord$Dict Int) + ({ + Eq0: \($__unused: Record {}@Type) -> + (eqInt: Eq$Dict Int), + compare: \(v: Int) -> + \(v1: Int) -> + (42: Int) + }: { compare :: Int -> Int -> Int, Eq0 :: Record {}@Type -> Eq$Dict Int }) + +eq2IntBoolean :: (Eq2$Dict Int Boolean) +eq2IntBoolean = + (Eq2$Dict: { eq2 :: Int -> Boolean -> Boolean } -> (Eq2$Dict Int Boolean)) + ({ eq2: \(v: Int) -> \(v1: Boolean) -> (true: Boolean) }: { + eq2 :: Int -> + Boolean -> Boolean + }) + +testasum :: ASum -> Int +testasum = + \(x: ASum) -> + case (x: ASum) of + Constr1 y -> (1: Int) + Constr2 z -> (2: Int) + +testBuiltin :: Int +testBuiltin = (addInteger: Int -> Int -> Int) (1: Int) (2: Int) + +testBinders :: TestBinderSum -> Int +testBinders = + \(x: TestBinderSum) -> + case (x: TestBinderSum) of + a@ConInt 3 -> (1: Int) + ConInt a -> (a: Int) + ConInts [3] -> (2: Int) + ConInts [a, b] -> (b: Int) + ConBoolean true -> (4: Int) + ConChar '\n' -> (5: Int) + ConNested ConInt 2 -> (6: Int) + ConQuantified f -> (f: forall (x :: Type). x -> Int) ("hello": String) + ConConstrained f -> + (f: forall (x :: Type). Eq$Dict x -> x -> Int) + (eqInt: Eq$Dict Int) + (2: Int) + ConNested other -> (7: Int) + ConObject obj -> (obj: { objField :: Int }).objField + ConObjectQuantified objQ -> + ((objQ: { objFieldQ :: forall (x :: Type). x -> Int }) + .objFieldQ) + ("world": String) + ConObject { objField: f } -> (f: Int) + _ -> (0: Int) + +recG1 :: forall (x :: Type). x -> Int +recG1 = \(x: x) -> (recF1: forall (x :: Type). x -> Int) (x: x) +recF1 :: forall (x :: Type). x -> Int +recF1 = \(x: x) -> (recG1: forall (x :: Type). x -> Int) (x: x) + +polyInObj :: { bar :: forall (x :: Type). x -> Int, baz :: Int } +polyInObj = + let + go :: forall (y :: Type). y -> Int + go = \(v: y) -> (5: Int) + in ({ + baz: (100: Int), + bar: (go: forall (y :: Type). y -> Int) + }: { bar :: forall (x :: Type). x -> Int, baz :: Int }) + +polyInObjMatch :: Int +polyInObjMatch = + case (polyInObj: { bar :: forall (x :: Type). x -> Int, baz :: Int }) of + { bar: f, baz: _ } -> (f: forall (x :: Type). x -> Int) ("hello": String) + +plus :: Int -> Int -> Int +plus = + \(a: Int) -> \(b: Int) -> (addInteger: Int -> Int -> Int) (a: Int) (b: Int) + +nestedBinds :: Int +nestedBinds = + let + g :: forall (a :: Type). a -> Int + g = \(v: a) -> (5: Int) + f :: Int -> Int + f = \(v: Int) -> (4: Int) + h :: Int + h = + let + i :: Int + i = (g: forall (a :: Type). a -> Int) ("hello": String) + j :: Int + j = (f: Int -> Int) (i: Int) + in (f: Int -> Int) (j: Int) + in (h: Int) + +nestedApplications :: Int +nestedApplications = + let + i :: Int -> Int -> Int + i = \(x: Int) -> \(v: Int) -> (x: Int) + h :: Int -> Int + h = + \(v: Int) -> + case (v: Int) of + 2 -> (3: Int) + _ -> (5: Int) + g :: Int -> Int + g = \(v: Int) -> (5: Int) + f :: Int -> Int + f = \(x: Int) -> (x: Int) + in (i: Int -> Int -> Int) + ((f: Int -> Int) ((g: Int -> Int) ((h: Int -> Int) (2: Int)))) + (4: Int) + +mutuallyRecursiveBindingGroupNoTypes :: Int +mutuallyRecursiveBindingGroupNoTypes = + let + h' :: Int -> Int -> Int + h' = \(x: Int) -> \(y: Int) -> (y: Int) + g' :: Int -> Int + g' = + \(y: Int) -> (h': Int -> Int -> Int) ((f': Int -> Int) (y: Int)) (3: Int) + f' :: Int -> Int + f' = \(x: Int) -> (g': Int -> Int) (2: Int) + in (g': Int -> Int) (3: Int) + +mutuallyRecursiveBindingGroup :: Int +mutuallyRecursiveBindingGroup = + let + h :: Int -> Int -> Int + h = \(x: Int) -> \(y: Int) -> (y: Int) + g :: Int -> Int + g = \(y: Int) -> (h: Int -> Int -> Int) ((f: Int -> Int) (y: Int)) (3: Int) + f :: Int -> Int + f = \(x: Int) -> (g: Int -> Int) (2: Int) + in (g: Int -> Int) (3: Int) + +minus :: Int -> Int -> Int +minus = \(v: Int) -> \(v1: Int) -> (42: Int) + +main :: Int +main = (plus: Int -> Int -> Int) (1: Int) (1: Int) + +id :: forall (t :: Type). t -> t +id = \(x: t) -> (x: t) + +objForall :: forall (a :: Type) (b :: Type). { getIdA :: a -> a, getIdB :: b -> b } +objForall = + ({ + getIdB: (id: forall (t :: Type). t -> t), + getIdA: (id: forall (t :: Type). t -> t) + }: forall (a :: Type) (b :: Type). { getIdA :: a -> a, getIdB :: b -> b }) + +eq2 :: forall (@a :: Type) (@b :: Type). (Eq2$Dict a b) -> a -> b -> Boolean +eq2 = + \(dict: (Eq2$Dict a b)) -> + case (dict: (Eq2$Dict a b)) of + Eq2$Dict v -> (v: { eq2 :: a -> b -> Boolean }).eq2 + +testEq2 :: Boolean +testEq2 = + (eq2: forall (@a :: Type) (@b :: Type). (Eq2$Dict a b) -> a -> b -> Boolean) + (eq2IntBoolean: (Eq2$Dict Int Boolean)) + (101: Int) + (false: Boolean) + +eq :: forall (@a :: Type). Eq$Dict a -> a -> a -> Boolean +eq = + \(dict: Eq$Dict a) -> + case (dict: Eq$Dict a) of + Eq$Dict v -> (v: { eq :: a -> a -> Boolean }).eq + +testEq :: Boolean +testEq = + (eq: forall (@a :: Type). Eq$Dict a -> a -> a -> Boolean) + (eqInt: Eq$Dict Int) + (1: Int) + (2: Int) + +testEqViaOrd :: forall (a :: Type). Ord$Dict a -> a -> a -> Boolean +testEqViaOrd = + \(dictOrd: Ord$Dict a) -> + \(a: a) -> + \(b: a) -> + (eq: forall (@a :: Type). Eq$Dict a -> a -> a -> Boolean) + (((dictOrd: Ord$Dict a).Eq0) ({ }: Record {})) + (a: a) + (b: a) + +workingEven :: Int -> Int +workingEven = + \(n: Int) -> + case ((eq: forall (@a :: Type). Eq$Dict a -> a -> a -> Boolean) (eqInt: Eq$Dict Int) (n: Int) (0: Int)) of + true -> (1: Int) + _ -> (42: Int) + +emptyList :: forall (t121 :: Type). Array (t121) +emptyList = ([]: forall (t121 :: Type). Array (t121)) + +cons :: forall (a :: Type). a -> Array (a) -> Array (a) +cons = \(x: a) -> \(xs: Array (a)) -> ([(x: a)]: Array (a)) + +consEmptyList1 :: Array (Int) +consEmptyList1 = + (cons: forall (a :: Type). a -> Array (a) -> Array (a)) + (1: Int) + (emptyList: forall (t121 :: Type). Array (t121)) + +consEmptyList2 :: Array (String) +consEmptyList2 = + (cons: forall (a :: Type). a -> Array (a) -> Array (a)) + ("hello": String) + (emptyList: forall (t121 :: Type). Array (t121)) + +compare :: forall (@a :: Type). Ord$Dict a -> a -> a -> Int +compare = + \(dict: Ord$Dict a) -> + case (dict: Ord$Dict a) of + Ord$Dict v -> + (v: { compare :: a -> a -> Int, Eq0 :: Record {}@Type -> Eq$Dict a }) + .compare + +brokenEven :: Int -> Int +brokenEven = + \(n: Int) -> + case ((eq: forall (@a :: Type). Eq$Dict a -> a -> a -> Boolean) (eqInt: Eq$Dict Int) (n: Int) (0: Int)) of + true -> (1: Int) + _ -> + (brokenEven: Int -> Int) ((minus: Int -> Int -> Int) (n: Int) (2: Int)) + +arrForall :: forall (a :: Type). Array (a -> a) +arrForall = + ([(id: forall (t :: Type). t -> t)]: forall (a :: Type). Array (a -> a)) + +anObj :: { foo :: Int } +anObj = ({ foo: (3: Int) }: { foo :: Int }) + +objUpdate :: { foo :: Int } +objUpdate = + let + v :: { foo :: Int } + v = (anObj: { foo :: Int }) + in (v: { foo :: Int }) { foo = (4: Int) } + +anIntLit :: Int +anIntLit = (1: Int) + +aVal :: Int +aVal = (1: Int) + +aStringLit :: String +aStringLit = ("woop": String) + +aPred :: Int -> Boolean +aPred = \(v: Int) -> (true: Boolean) + +guardedCase :: Int -> Int -> Int +guardedCase = + \(w: Int) -> + \(x: Int) -> + let + v :: forall $23. $23 -> Int + v = \(v1: $23) -> (0: Int) + in case (w: Int) (x: Int) of + y z -> + let + v1 :: Boolean + v1 = + (eq: forall (@a :: Type). Eq$Dict a -> a -> a -> Boolean) + (eqInt: Eq$Dict Int) + (y: Int) + (2: Int) + in case (v1: Boolean) of + true -> + let + v2 :: Boolean + v2 = (aPred: Int -> Boolean) (y: Int) + in case (v2: Boolean) of + true -> + let + v3 :: Boolean + v3 = + (eq: forall (@a :: Type). Eq$Dict a -> + a -> a -> Boolean) + (eqInt: Eq$Dict Int) + (z: Int) + (0: Int) + in case (v3: Boolean) of + true -> + let + v4 :: Boolean + v4 = + (eq: forall (@a :: Type). Eq$Dict a -> + a -> a -> Boolean) + (eqInt: Eq$Dict Int) + (y: Int) + (nestedBinds: Int) + in case (v4: Boolean) of + true -> (2: Int) + _ -> + (v: forall $23. $23 -> Int) + (true: Boolean) + _ -> + (v: forall $23. $23 -> Int) + (true: Boolean) + _ -> (v: forall $23. $23 -> Int) (true: Boolean) + _ -> (v: forall $23. $23 -> Int) (true: Boolean) + +aList :: Array (Int) +aList = ([(1: Int), (2: Int), (3: Int), (4: Int), (5: Int)]: Array (Int)) + +aFunction4 :: forall (r :: Row Type). { a :: Int | r } -> Int +aFunction4 = \(r: { a :: Int | r }) -> (r: { a :: Int | r }).a + +aFunction5 :: Int +aFunction5 = + (aFunction4: forall (r :: Row Type). { a :: Int | r } -> Int) + ({ a: (2: Int) }: { a :: Int }) + +aFunction3 :: Int -> Int +aFunction3 = + \(x: Int) -> + case ((eq: forall (@a :: Type). Eq$Dict a -> a -> a -> Boolean) (eqInt: Eq$Dict Int) (x: Int) (2: Int)) of + true -> (4: Int) + _ -> (1: Int) + +aFunction2 :: Int -> Array (Int) +aFunction2 = \(x: Int) -> ([(x: Int), (1: Int)]: Array (Int)) + +aFunction :: forall (x :: Type). x -> forall (y :: Type). y -> Int -> Int +aFunction = + \(any: x) -> + \(f: forall (y :: Type). y -> Int) -> + (f: forall (y :: Type). y -> Int) (any: x) + +aFunction6 :: Int +aFunction6 = + let + go :: forall (z :: Type). z -> Int + go = \(v: z) -> (10: Int) + in (aFunction: forall (x :: Type). x -> forall (y :: Type). y -> Int -> Int) + ([]: Array (t151)) + (go: forall (z :: Type). z -> Int) + +aBool :: Boolean +aBool = (true: Boolean) \ No newline at end of file diff --git a/tests/purus/passing/Misc/output/package.json b/tests/purus/passing/Misc/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/Misc/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ModuleDeps/M1.purs b/tests/purus/passing/ModuleDeps/M1.purs new file mode 100644 index 000000000..535aa287c --- /dev/null +++ b/tests/purus/passing/ModuleDeps/M1.purs @@ -0,0 +1,5 @@ +module M1 where + +import M2 as M2 + +foo = M2.bar diff --git a/tests/purus/passing/ModuleDeps/M2.purs b/tests/purus/passing/ModuleDeps/M2.purs new file mode 100644 index 000000000..017e70e3f --- /dev/null +++ b/tests/purus/passing/ModuleDeps/M2.purs @@ -0,0 +1,5 @@ +module M2 where + +import M3 as M3 + +bar = M3.baz diff --git a/tests/purus/passing/ModuleDeps/M3.purs b/tests/purus/passing/ModuleDeps/M3.purs new file mode 100644 index 000000000..f07167b71 --- /dev/null +++ b/tests/purus/passing/ModuleDeps/M3.purs @@ -0,0 +1,3 @@ +module M3 where + +baz = 1 diff --git a/tests/purus/passing/ModuleDeps/output/M1/externs.cbor b/tests/purus/passing/ModuleDeps/output/M1/externs.cbor new file mode 100644 index 000000000..923d4de15 Binary files /dev/null and b/tests/purus/passing/ModuleDeps/output/M1/externs.cbor differ diff --git a/tests/purus/passing/ModuleDeps/output/M1/index.cfn b/tests/purus/passing/ModuleDeps/output/M1/index.cfn new file mode 100644 index 000000000..00e72fefd --- /dev/null +++ b/tests/purus/passing/ModuleDeps/output/M1/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,13],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[5,13],"start":[5,7]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"bar","moduleName":["M2"]}},"identifier":"foo"}],"exports":["foo"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,13],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,13],"start":[1,1]}},"moduleName":["M2"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,13],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M1"],"modulePath":"tests/purus/passing/ModuleDeps/M1.purs","reExports":{},"sourceSpan":{"end":[5,13],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ModuleDeps/output/M1/index.cfn.pretty b/tests/purus/passing/ModuleDeps/output/M1/index.cfn.pretty new file mode 100644 index 000000000..fba52bf8c --- /dev/null +++ b/tests/purus/passing/ModuleDeps/output/M1/index.cfn.pretty @@ -0,0 +1,14 @@ +M1 (tests/purus/passing/ModuleDeps/M1.purs) +Imported Modules: + Builtin, + M2, + Prim +Exports: + foo +Re-Exports: + +Foreign: + +Declarations: +foo :: Int +foo = (bar: Int) \ No newline at end of file diff --git a/tests/purus/passing/ModuleDeps/output/M2/externs.cbor b/tests/purus/passing/ModuleDeps/output/M2/externs.cbor new file mode 100644 index 000000000..2a7641000 Binary files /dev/null and b/tests/purus/passing/ModuleDeps/output/M2/externs.cbor differ diff --git a/tests/purus/passing/ModuleDeps/output/M2/index.cfn b/tests/purus/passing/ModuleDeps/output/M2/index.cfn new file mode 100644 index 000000000..1ea1b2e4d --- /dev/null +++ b/tests/purus/passing/ModuleDeps/output/M2/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,13],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[5,13],"start":[5,7]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"baz","moduleName":["M3"]}},"identifier":"bar"}],"exports":["bar"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,13],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,13],"start":[1,1]}},"moduleName":["M3"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,13],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M2"],"modulePath":"tests/purus/passing/ModuleDeps/M2.purs","reExports":{},"sourceSpan":{"end":[5,13],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ModuleDeps/output/M2/index.cfn.pretty b/tests/purus/passing/ModuleDeps/output/M2/index.cfn.pretty new file mode 100644 index 000000000..682e4e44e --- /dev/null +++ b/tests/purus/passing/ModuleDeps/output/M2/index.cfn.pretty @@ -0,0 +1,14 @@ +M2 (tests/purus/passing/ModuleDeps/M2.purs) +Imported Modules: + Builtin, + M3, + Prim +Exports: + bar +Re-Exports: + +Foreign: + +Declarations: +bar :: Int +bar = (baz: Int) \ No newline at end of file diff --git a/tests/purus/passing/ModuleDeps/output/M3/externs.cbor b/tests/purus/passing/ModuleDeps/output/M3/externs.cbor new file mode 100644 index 000000000..5053b861d Binary files /dev/null and b/tests/purus/passing/ModuleDeps/output/M3/externs.cbor differ diff --git a/tests/purus/passing/ModuleDeps/output/M3/index.cfn b/tests/purus/passing/ModuleDeps/output/M3/index.cfn new file mode 100644 index 000000000..d0fb81d28 --- /dev/null +++ b/tests/purus/passing/ModuleDeps/output/M3/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,8],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,8],"start":[3,7]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"identifier":"baz"}],"exports":["baz"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,8],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,8],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M3"],"modulePath":"tests/purus/passing/ModuleDeps/M3.purs","reExports":{},"sourceSpan":{"end":[3,8],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ModuleDeps/output/M3/index.cfn.pretty b/tests/purus/passing/ModuleDeps/output/M3/index.cfn.pretty new file mode 100644 index 000000000..119b4b637 --- /dev/null +++ b/tests/purus/passing/ModuleDeps/output/M3/index.cfn.pretty @@ -0,0 +1,13 @@ +M3 (tests/purus/passing/ModuleDeps/M3.purs) +Imported Modules: + Builtin, + Prim +Exports: + baz +Re-Exports: + +Foreign: + +Declarations: +baz :: Int +baz = (1: Int) \ No newline at end of file diff --git a/tests/purus/passing/ModuleDeps/output/package.json b/tests/purus/passing/ModuleDeps/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ModuleDeps/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/NonOrphanInstanceFunDepExtra/Lib.purs b/tests/purus/passing/NonOrphanInstanceFunDepExtra/Lib.purs new file mode 100644 index 000000000..590977109 --- /dev/null +++ b/tests/purus/passing/NonOrphanInstanceFunDepExtra/Lib.purs @@ -0,0 +1,4 @@ +module Lib where +-- covering sets: {{f, l}} +class C f l r | l -> r +data L diff --git a/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/Lib/externs.cbor b/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/Lib/externs.cbor new file mode 100644 index 000000000..f8b25d82b Binary files /dev/null and b/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/Lib/externs.cbor differ diff --git a/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/Lib/index.cfn b/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/Lib/index.cfn new file mode 100644 index 000000000..33d0c9f8f --- /dev/null +++ b/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/Lib/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"C$Dict":["newtype",[["f",null],["l",null],["r",null]],[{"dataCtorAnn":[{"end":[3,23],"name":"tests/purus/passing/NonOrphanInstanceFunDepExtra/Lib.purs","start":[3,1]},[{"LineComment":" covering sets: {{f, l}}"}]],"dataCtorFields":[[{"Ident":"dict"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}]],"dataCtorName":"C$Dict"}]],"L":["data",[],[]]},"decls":[{"annotation":{"meta":{"metaType":"IsTypeClassConstructor"},"sourceSpan":{"end":[3,23],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[3,23],"start":[3,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[3,23],"start":[3,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"C$Dict"}],"exports":[],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,7],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,7],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Lib"],"modulePath":"tests/purus/passing/NonOrphanInstanceFunDepExtra/Lib.purs","reExports":{},"sourceSpan":{"end":[4,7],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/Lib/index.cfn.pretty b/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/Lib/index.cfn.pretty new file mode 100644 index 000000000..0322641b8 --- /dev/null +++ b/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/Lib/index.cfn.pretty @@ -0,0 +1,13 @@ +Lib (tests/purus/passing/NonOrphanInstanceFunDepExtra/Lib.purs) +Imported Modules: + Builtin, + Prim +Exports: + +Re-Exports: + +Foreign: + +Declarations: +C$Dict :: Record {} -> Record {} +C$Dict = \(x: Record {}) -> (x: Record {}) \ No newline at end of file diff --git a/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/package.json b/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/NonOrphanInstanceFunDepExtra/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/NonOrphanInstanceMulti/Lib.purs b/tests/purus/passing/NonOrphanInstanceMulti/Lib.purs new file mode 100644 index 000000000..49b5b73e0 --- /dev/null +++ b/tests/purus/passing/NonOrphanInstanceMulti/Lib.purs @@ -0,0 +1,4 @@ +module Lib where +-- covering sets: {{l, r}} +class C l r +data R diff --git a/tests/purus/passing/NonOrphanInstanceMulti/output/Lib/externs.cbor b/tests/purus/passing/NonOrphanInstanceMulti/output/Lib/externs.cbor new file mode 100644 index 000000000..83a0e94c7 Binary files /dev/null and b/tests/purus/passing/NonOrphanInstanceMulti/output/Lib/externs.cbor differ diff --git a/tests/purus/passing/NonOrphanInstanceMulti/output/Lib/index.cfn b/tests/purus/passing/NonOrphanInstanceMulti/output/Lib/index.cfn new file mode 100644 index 000000000..a85a26198 --- /dev/null +++ b/tests/purus/passing/NonOrphanInstanceMulti/output/Lib/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"C$Dict":["newtype",[["l",null],["r",null]],[{"dataCtorAnn":[{"end":[3,12],"name":"tests/purus/passing/NonOrphanInstanceMulti/Lib.purs","start":[3,1]},[{"LineComment":" covering sets: {{l, r}}"}]],"dataCtorFields":[[{"Ident":"dict"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}]],"dataCtorName":"C$Dict"}]],"R":["data",[],[]]},"decls":[{"annotation":{"meta":{"metaType":"IsTypeClassConstructor"},"sourceSpan":{"end":[3,12],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[3,12],"start":[3,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[3,12],"start":[3,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"C$Dict"}],"exports":[],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,7],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,7],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Lib"],"modulePath":"tests/purus/passing/NonOrphanInstanceMulti/Lib.purs","reExports":{},"sourceSpan":{"end":[4,7],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/NonOrphanInstanceMulti/output/Lib/index.cfn.pretty b/tests/purus/passing/NonOrphanInstanceMulti/output/Lib/index.cfn.pretty new file mode 100644 index 000000000..6b72d79d1 --- /dev/null +++ b/tests/purus/passing/NonOrphanInstanceMulti/output/Lib/index.cfn.pretty @@ -0,0 +1,13 @@ +Lib (tests/purus/passing/NonOrphanInstanceMulti/Lib.purs) +Imported Modules: + Builtin, + Prim +Exports: + +Re-Exports: + +Foreign: + +Declarations: +C$Dict :: Record {} -> Record {} +C$Dict = \(x: Record {}) -> (x: Record {}) \ No newline at end of file diff --git a/tests/purus/passing/NonOrphanInstanceMulti/output/package.json b/tests/purus/passing/NonOrphanInstanceMulti/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/NonOrphanInstanceMulti/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports/A.purs b/tests/purus/passing/PendingConflictingImports/A.purs new file mode 100644 index 000000000..302b0328d --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports/A.purs @@ -0,0 +1,4 @@ +module A where + +thing :: Int +thing = 1 diff --git a/tests/purus/passing/PendingConflictingImports/B.purs b/tests/purus/passing/PendingConflictingImports/B.purs new file mode 100644 index 000000000..076bf7ea5 --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports/B.purs @@ -0,0 +1,4 @@ +module B where + +thing :: Int +thing = 2 diff --git a/tests/purus/passing/PendingConflictingImports/PendingConflictingImports.purs b/tests/purus/passing/PendingConflictingImports/PendingConflictingImports.purs new file mode 100644 index 000000000..b42cd06fd --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports/PendingConflictingImports.purs @@ -0,0 +1,8 @@ +module Main where + +-- No error as we never force `thing` to be resolved in `Main` +import A +import B + + +main = "Done" diff --git a/tests/purus/passing/PendingConflictingImports/output/A/externs.cbor b/tests/purus/passing/PendingConflictingImports/output/A/externs.cbor new file mode 100644 index 000000000..48749abf1 Binary files /dev/null and b/tests/purus/passing/PendingConflictingImports/output/A/externs.cbor differ diff --git a/tests/purus/passing/PendingConflictingImports/output/A/index.cfn b/tests/purus/passing/PendingConflictingImports/output/A/index.cfn new file mode 100644 index 000000000..25d49a14f --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports/output/A/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,13],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"identifier":"thing"}],"exports":["thing"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["A"],"modulePath":"tests/purus/passing/PendingConflictingImports/A.purs","reExports":{},"sourceSpan":{"end":[4,10],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports/output/A/index.cfn.pretty b/tests/purus/passing/PendingConflictingImports/output/A/index.cfn.pretty new file mode 100644 index 000000000..49b5bb341 --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports/output/A/index.cfn.pretty @@ -0,0 +1,13 @@ +A (tests/purus/passing/PendingConflictingImports/A.purs) +Imported Modules: + Builtin, + Prim +Exports: + thing +Re-Exports: + +Foreign: + +Declarations: +thing :: Int +thing = (1: Int) \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports/output/B/externs.cbor b/tests/purus/passing/PendingConflictingImports/output/B/externs.cbor new file mode 100644 index 000000000..64166ff20 Binary files /dev/null and b/tests/purus/passing/PendingConflictingImports/output/B/externs.cbor differ diff --git a/tests/purus/passing/PendingConflictingImports/output/B/index.cfn b/tests/purus/passing/PendingConflictingImports/output/B/index.cfn new file mode 100644 index 000000000..d0a43a356 --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports/output/B/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,13],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"identifier":"thing"}],"exports":["thing"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["B"],"modulePath":"tests/purus/passing/PendingConflictingImports/B.purs","reExports":{},"sourceSpan":{"end":[4,10],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports/output/B/index.cfn.pretty b/tests/purus/passing/PendingConflictingImports/output/B/index.cfn.pretty new file mode 100644 index 000000000..b6e55870c --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports/output/B/index.cfn.pretty @@ -0,0 +1,13 @@ +B (tests/purus/passing/PendingConflictingImports/B.purs) +Imported Modules: + Builtin, + Prim +Exports: + thing +Re-Exports: + +Foreign: + +Declarations: +thing :: Int +thing = (2: Int) \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports/output/Main/externs.cbor b/tests/purus/passing/PendingConflictingImports/output/Main/externs.cbor new file mode 100644 index 000000000..d757b9c6d Binary files /dev/null and b/tests/purus/passing/PendingConflictingImports/output/Main/externs.cbor differ diff --git a/tests/purus/passing/PendingConflictingImports/output/Main/index.cfn b/tests/purus/passing/PendingConflictingImports/output/Main/index.cfn new file mode 100644 index 000000000..469412474 --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports/output/Main/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[8,14],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[8,14],"start":[8,8]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"Done"}},"identifier":"main"}],"exports":["main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,9],"start":[4,1]}},"moduleName":["A"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,9],"start":[5,1]}},"moduleName":["B"]},{"annotation":{"meta":null,"sourceSpan":{"end":[8,14],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[8,14],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Main"],"modulePath":"tests/purus/passing/PendingConflictingImports/PendingConflictingImports.purs","reExports":{},"sourceSpan":{"end":[8,14],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports/output/Main/index.cfn.pretty b/tests/purus/passing/PendingConflictingImports/output/Main/index.cfn.pretty new file mode 100644 index 000000000..bb0ee29dd --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports/output/Main/index.cfn.pretty @@ -0,0 +1,15 @@ +Main (tests/purus/passing/PendingConflictingImports/PendingConflictingImports.purs) +Imported Modules: + A, + B, + Builtin, + Prim +Exports: + main +Re-Exports: + +Foreign: + +Declarations: +main :: String +main = ("Done": String) \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports/output/package.json b/tests/purus/passing/PendingConflictingImports/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports2/A.purs b/tests/purus/passing/PendingConflictingImports2/A.purs new file mode 100644 index 000000000..302b0328d --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports2/A.purs @@ -0,0 +1,4 @@ +module A where + +thing :: Int +thing = 1 diff --git a/tests/purus/passing/PendingConflictingImports2/PendingConflictingImports2.purs b/tests/purus/passing/PendingConflictingImports2/PendingConflictingImports2.purs new file mode 100644 index 000000000..81c3d821d --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports2/PendingConflictingImports2.purs @@ -0,0 +1,9 @@ +module Main where + +import A + +-- No error as we never force `thing` to be resolved in `Main` +thing :: Int +thing = 2 + +main = "Done" diff --git a/tests/purus/passing/PendingConflictingImports2/output/A/externs.cbor b/tests/purus/passing/PendingConflictingImports2/output/A/externs.cbor new file mode 100644 index 000000000..0a92ab5fc Binary files /dev/null and b/tests/purus/passing/PendingConflictingImports2/output/A/externs.cbor differ diff --git a/tests/purus/passing/PendingConflictingImports2/output/A/index.cfn b/tests/purus/passing/PendingConflictingImports2/output/A/index.cfn new file mode 100644 index 000000000..d0395b422 --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports2/output/A/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,13],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"identifier":"thing"}],"exports":["thing"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["A"],"modulePath":"tests/purus/passing/PendingConflictingImports2/A.purs","reExports":{},"sourceSpan":{"end":[4,10],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports2/output/A/index.cfn.pretty b/tests/purus/passing/PendingConflictingImports2/output/A/index.cfn.pretty new file mode 100644 index 000000000..8afb3968e --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports2/output/A/index.cfn.pretty @@ -0,0 +1,13 @@ +A (tests/purus/passing/PendingConflictingImports2/A.purs) +Imported Modules: + Builtin, + Prim +Exports: + thing +Re-Exports: + +Foreign: + +Declarations: +thing :: Int +thing = (1: Int) \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports2/output/Main/externs.cbor b/tests/purus/passing/PendingConflictingImports2/output/Main/externs.cbor new file mode 100644 index 000000000..44bf928fa Binary files /dev/null and b/tests/purus/passing/PendingConflictingImports2/output/Main/externs.cbor differ diff --git a/tests/purus/passing/PendingConflictingImports2/output/Main/index.cfn b/tests/purus/passing/PendingConflictingImports2/output/Main/index.cfn new file mode 100644 index 000000000..c73023971 --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports2/output/Main/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,13],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,10],"start":[7,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"identifier":"thing"},{"annotation":{"meta":null,"sourceSpan":{"end":[9,15],"start":[9,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[9,15],"start":[9,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"Done"}},"identifier":"main"}],"exports":["thing","main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[3,1]}},"moduleName":["A"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,15],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,15],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Main"],"modulePath":"tests/purus/passing/PendingConflictingImports2/PendingConflictingImports2.purs","reExports":{},"sourceSpan":{"end":[9,15],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports2/output/Main/index.cfn.pretty b/tests/purus/passing/PendingConflictingImports2/output/Main/index.cfn.pretty new file mode 100644 index 000000000..5503e8d83 --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports2/output/Main/index.cfn.pretty @@ -0,0 +1,18 @@ +Main (tests/purus/passing/PendingConflictingImports2/PendingConflictingImports2.purs) +Imported Modules: + A, + Builtin, + Prim +Exports: + thing, + main +Re-Exports: + +Foreign: + +Declarations: +thing :: Int +thing = (2: Int) + +main :: String +main = ("Done": String) \ No newline at end of file diff --git a/tests/purus/passing/PendingConflictingImports2/output/package.json b/tests/purus/passing/PendingConflictingImports2/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/PendingConflictingImports2/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ReExportQualified/A.purs b/tests/purus/passing/ReExportQualified/A.purs new file mode 100644 index 000000000..ae231283a --- /dev/null +++ b/tests/purus/passing/ReExportQualified/A.purs @@ -0,0 +1,3 @@ +module A where + +x = "Do" diff --git a/tests/purus/passing/ReExportQualified/B.purs b/tests/purus/passing/ReExportQualified/B.purs new file mode 100644 index 000000000..2e149222f --- /dev/null +++ b/tests/purus/passing/ReExportQualified/B.purs @@ -0,0 +1,3 @@ +module B where + +y = "ne" diff --git a/tests/purus/passing/ReExportQualified/C.purs b/tests/purus/passing/ReExportQualified/C.purs new file mode 100644 index 000000000..589f37bc4 --- /dev/null +++ b/tests/purus/passing/ReExportQualified/C.purs @@ -0,0 +1,4 @@ +module C (module A, module M2) where + +import A +import B as M2 diff --git a/tests/purus/passing/ReExportQualified/ReExportQualified.purs b/tests/purus/passing/ReExportQualified/ReExportQualified.purs new file mode 100644 index 000000000..af2f8d272 --- /dev/null +++ b/tests/purus/passing/ReExportQualified/ReExportQualified.purs @@ -0,0 +1,9 @@ +module Main where + +import C + + +concat :: String -> String -> String +concat _ _ = "concat" + +main = x `concat` y diff --git a/tests/purus/passing/ReExportQualified/output/A/externs.cbor b/tests/purus/passing/ReExportQualified/output/A/externs.cbor new file mode 100644 index 000000000..fd329f999 Binary files /dev/null and b/tests/purus/passing/ReExportQualified/output/A/externs.cbor differ diff --git a/tests/purus/passing/ReExportQualified/output/A/index.cfn b/tests/purus/passing/ReExportQualified/output/A/index.cfn new file mode 100644 index 000000000..4101795de --- /dev/null +++ b/tests/purus/passing/ReExportQualified/output/A/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[3,5]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"Do"}},"identifier":"x"}],"exports":["x"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["A"],"modulePath":"tests/purus/passing/ReExportQualified/A.purs","reExports":{},"sourceSpan":{"end":[3,9],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ReExportQualified/output/A/index.cfn.pretty b/tests/purus/passing/ReExportQualified/output/A/index.cfn.pretty new file mode 100644 index 000000000..829a9c730 --- /dev/null +++ b/tests/purus/passing/ReExportQualified/output/A/index.cfn.pretty @@ -0,0 +1,13 @@ +A (tests/purus/passing/ReExportQualified/A.purs) +Imported Modules: + Builtin, + Prim +Exports: + x +Re-Exports: + +Foreign: + +Declarations: +x :: String +x = ("Do": String) \ No newline at end of file diff --git a/tests/purus/passing/ReExportQualified/output/B/externs.cbor b/tests/purus/passing/ReExportQualified/output/B/externs.cbor new file mode 100644 index 000000000..4f34888c9 Binary files /dev/null and b/tests/purus/passing/ReExportQualified/output/B/externs.cbor differ diff --git a/tests/purus/passing/ReExportQualified/output/B/index.cfn b/tests/purus/passing/ReExportQualified/output/B/index.cfn new file mode 100644 index 000000000..d2d6dbe48 --- /dev/null +++ b/tests/purus/passing/ReExportQualified/output/B/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[3,5]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"ne"}},"identifier":"y"}],"exports":["y"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["B"],"modulePath":"tests/purus/passing/ReExportQualified/B.purs","reExports":{},"sourceSpan":{"end":[3,9],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ReExportQualified/output/B/index.cfn.pretty b/tests/purus/passing/ReExportQualified/output/B/index.cfn.pretty new file mode 100644 index 000000000..333af29dd --- /dev/null +++ b/tests/purus/passing/ReExportQualified/output/B/index.cfn.pretty @@ -0,0 +1,13 @@ +B (tests/purus/passing/ReExportQualified/B.purs) +Imported Modules: + Builtin, + Prim +Exports: + y +Re-Exports: + +Foreign: + +Declarations: +y :: String +y = ("ne": String) \ No newline at end of file diff --git a/tests/purus/passing/ReExportQualified/output/C/externs.cbor b/tests/purus/passing/ReExportQualified/output/C/externs.cbor new file mode 100644 index 000000000..d55a990fc Binary files /dev/null and b/tests/purus/passing/ReExportQualified/output/C/externs.cbor differ diff --git a/tests/purus/passing/ReExportQualified/output/C/index.cfn b/tests/purus/passing/ReExportQualified/output/C/index.cfn new file mode 100644 index 000000000..d4aadc99c --- /dev/null +++ b/tests/purus/passing/ReExportQualified/output/C/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[],"exports":[],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[3,1]}},"moduleName":["A"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[4,1]}},"moduleName":["B"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,15],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["C"],"modulePath":"tests/purus/passing/ReExportQualified/C.purs","reExports":{"A":["x"],"B":["y"]},"sourceSpan":{"end":[4,15],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ReExportQualified/output/C/index.cfn.pretty b/tests/purus/passing/ReExportQualified/output/C/index.cfn.pretty new file mode 100644 index 000000000..6ab09c442 --- /dev/null +++ b/tests/purus/passing/ReExportQualified/output/C/index.cfn.pretty @@ -0,0 +1,14 @@ +C (tests/purus/passing/ReExportQualified/C.purs) +Imported Modules: + A, + B, + Builtin, + Prim +Exports: + +Re-Exports: + A.x, + B.y +Foreign: + +Declarations: diff --git a/tests/purus/passing/ReExportQualified/output/Main/externs.cbor b/tests/purus/passing/ReExportQualified/output/Main/externs.cbor new file mode 100644 index 000000000..533f82ceb Binary files /dev/null and b/tests/purus/passing/ReExportQualified/output/Main/externs.cbor differ diff --git a/tests/purus/passing/ReExportQualified/output/Main/index.cfn b/tests/purus/passing/ReExportQualified/output/Main/index.cfn new file mode 100644 index 000000000..2923e5a7c --- /dev/null +++ b/tests/purus/passing/ReExportQualified/output/Main/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,37],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,22],"start":[7,1]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[7,22],"start":[7,1]}},"argument":"v1","body":{"annotation":{"meta":null,"sourceSpan":{"end":[7,22],"start":[7,14]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"concat"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,27],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,21]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,37],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,31]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,11]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,37],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,21]},[]],"contents":[{"annotation":[{"end":[6,37],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,21]},[]],"contents":[{"annotation":[{"end":[6,30],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,28]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,27],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,21]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,37],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,31]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"}},"identifier":"concat"},{"annotation":{"meta":null,"sourceSpan":{"end":[9,20],"start":[9,1]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[9,17],"start":[9,11]}},"kind":"Var","type":{"annotation":[{"end":[6,37],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,37],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,20],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,18]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,11]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,37],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,21]},[]],"contents":[{"annotation":[{"end":[6,37],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,21]},[]],"contents":[{"annotation":[{"end":[6,30],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,28]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,27],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,21]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[6,37],"name":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","start":[6,31]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"concat","moduleName":["Main"]}},"annotation":{"meta":null,"sourceSpan":{"end":[9,20],"start":[9,8]}},"argument":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[9,9],"start":[9,8]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"identifier":"x","moduleName":["A"]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[9,20],"start":[9,8]}},"argument":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[9,20],"start":[9,19]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"identifier":"y","moduleName":["B"]}},"kind":"App"},"identifier":"main"}],"exports":["concat","main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[9,20],"start":[1,1]}},"moduleName":["A"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,20],"start":[1,1]}},"moduleName":["B"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,20],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[3,1]}},"moduleName":["C"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,20],"start":[1,1]}},"moduleName":["Main"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,20],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Main"],"modulePath":"tests/purus/passing/ReExportQualified/ReExportQualified.purs","reExports":{},"sourceSpan":{"end":[9,20],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ReExportQualified/output/Main/index.cfn.pretty b/tests/purus/passing/ReExportQualified/output/Main/index.cfn.pretty new file mode 100644 index 000000000..2adba04cd --- /dev/null +++ b/tests/purus/passing/ReExportQualified/output/Main/index.cfn.pretty @@ -0,0 +1,21 @@ +Main (tests/purus/passing/ReExportQualified/ReExportQualified.purs) +Imported Modules: + A, + B, + Builtin, + C, + Main, + Prim +Exports: + concat, + main +Re-Exports: + +Foreign: + +Declarations: +concat :: String -> String -> String +concat = \(v: String) -> \(v1: String) -> ("concat": String) + +main :: String +main = (concat: String -> String -> String) (x: String) (y: String) \ No newline at end of file diff --git a/tests/purus/passing/ReExportQualified/output/package.json b/tests/purus/passing/ReExportQualified/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ReExportQualified/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/RedefinedFixity/M1.purs b/tests/purus/passing/RedefinedFixity/M1.purs new file mode 100644 index 000000000..703e37bfb --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/M1.purs @@ -0,0 +1,6 @@ +module M1 where + +applyFn :: forall a b. (forall c d. c -> d) -> a -> b +applyFn f a = f a + +infixr 1000 applyFn as $ diff --git a/tests/purus/passing/RedefinedFixity/M2.purs b/tests/purus/passing/RedefinedFixity/M2.purs new file mode 100644 index 000000000..f7ddf1946 --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/M2.purs @@ -0,0 +1,3 @@ +module M2 where + +import M1 diff --git a/tests/purus/passing/RedefinedFixity/M3.purs b/tests/purus/passing/RedefinedFixity/M3.purs new file mode 100644 index 000000000..cd62cc115 --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/M3.purs @@ -0,0 +1,4 @@ +module M3 where + +import M1 +import M2 diff --git a/tests/purus/passing/RedefinedFixity/RedefinedFixity.purs b/tests/purus/passing/RedefinedFixity/RedefinedFixity.purs new file mode 100644 index 000000000..a796c5790 --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/RedefinedFixity.purs @@ -0,0 +1,5 @@ +module Main where + +import M3 + +main = "Done" diff --git a/tests/purus/passing/RedefinedFixity/output/M1/externs.cbor b/tests/purus/passing/RedefinedFixity/output/M1/externs.cbor new file mode 100644 index 000000000..46e535796 Binary files /dev/null and b/tests/purus/passing/RedefinedFixity/output/M1/externs.cbor differ diff --git a/tests/purus/passing/RedefinedFixity/output/M1/index.cfn b/tests/purus/passing/RedefinedFixity/output/M1/index.cfn new file mode 100644 index 000000000..5d5a9d4c1 --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/output/M1/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,54],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,1]}},"argument":"f","body":{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,1]}},"argument":"a","body":{"abstraction":{"annotation":{"meta":null,"sourceSpan":{"end":[4,16],"start":[4,15]}},"kind":"Var","type":{"annotation":[{"end":[3,43],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,25]},[]],"contents":{"identifier":"c","kind":{"annotation":[{"end":[3,41],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,39]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":1,"type":{"annotation":[{"end":[3,43],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,34]},[]],"contents":{"identifier":"d","kind":{"annotation":[{"end":[3,41],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,39]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":0,"type":{"annotation":[{"end":[3,43],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,37]},[]],"contents":[{"annotation":[{"end":[3,43],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,37]},[]],"contents":[{"annotation":[{"end":[3,41],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,39]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,38],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,37]},[]],"contents":"c","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[3,43],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,42]},[]],"contents":"d","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"f","sourcePos":[4,1]}},"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,15]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[4,18],"start":[4,17]}},"kind":"Var","type":{"annotation":[{"end":[3,49],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,48]},[]],"contents":"a","tag":"TypeVar"},"value":{"identifier":"a","sourcePos":[4,1]}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,49],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,48]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[3,54],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,53]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[3,54],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,12]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[3,52],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,50]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":3,"type":{"annotation":[{"end":[3,54],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,21]},[]],"contents":{"identifier":"b","kind":{"annotation":[{"end":[3,52],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,50]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":2,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,43],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,25]},[]],"contents":{"identifier":"c","kind":{"annotation":[{"end":[3,41],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,39]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":1,"type":{"annotation":[{"end":[3,43],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,34]},[]],"contents":{"identifier":"d","kind":{"annotation":[{"end":[3,41],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,39]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":0,"type":{"annotation":[{"end":[3,43],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,37]},[]],"contents":[{"annotation":[{"end":[3,43],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,37]},[]],"contents":[{"annotation":[{"end":[3,41],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,39]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,38],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,37]},[]],"contents":"c","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[3,43],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,42]},[]],"contents":"d","tag":"TypeVar"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}],"tag":"TypeApp"},{"annotation":[{"end":[3,54],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,48]},[]],"contents":[{"annotation":[{"end":[3,54],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,48]},[]],"contents":[{"annotation":[{"end":[3,52],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,50]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,49],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,48]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[3,54],"name":"tests/purus/passing/RedefinedFixity/M1.purs","start":[3,53]},[]],"contents":"b","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"applyFn"}],"exports":["applyFn"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,25],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,25],"start":[1,1]}},"moduleName":["M1"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,25],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M1"],"modulePath":"tests/purus/passing/RedefinedFixity/M1.purs","reExports":{},"sourceSpan":{"end":[6,25],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/RedefinedFixity/output/M1/index.cfn.pretty b/tests/purus/passing/RedefinedFixity/output/M1/index.cfn.pretty new file mode 100644 index 000000000..a5c0cd44d --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/output/M1/index.cfn.pretty @@ -0,0 +1,17 @@ +M1 (tests/purus/passing/RedefinedFixity/M1.purs) +Imported Modules: + Builtin, + M1, + Prim +Exports: + applyFn +Re-Exports: + +Foreign: + +Declarations: +applyFn :: forall (a :: Type) (b :: Type). forall (c :: Type) (d :: Type). c -> d -> a -> b +applyFn = + \(f: forall (c :: Type) (d :: Type). c -> d) -> + \(a: a) -> + (f: forall (c :: Type) (d :: Type). c -> d) (a: a) \ No newline at end of file diff --git a/tests/purus/passing/RedefinedFixity/output/M2/externs.cbor b/tests/purus/passing/RedefinedFixity/output/M2/externs.cbor new file mode 100644 index 000000000..224a65020 Binary files /dev/null and b/tests/purus/passing/RedefinedFixity/output/M2/externs.cbor differ diff --git a/tests/purus/passing/RedefinedFixity/output/M2/index.cfn b/tests/purus/passing/RedefinedFixity/output/M2/index.cfn new file mode 100644 index 000000000..adc78281f --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/output/M2/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[],"exports":[],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,10],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,10],"start":[3,1]}},"moduleName":["M1"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M2"],"modulePath":"tests/purus/passing/RedefinedFixity/M2.purs","reExports":{},"sourceSpan":{"end":[3,10],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/RedefinedFixity/output/M2/index.cfn.pretty b/tests/purus/passing/RedefinedFixity/output/M2/index.cfn.pretty new file mode 100644 index 000000000..147a33e69 --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/output/M2/index.cfn.pretty @@ -0,0 +1,12 @@ +M2 (tests/purus/passing/RedefinedFixity/M2.purs) +Imported Modules: + Builtin, + M1, + Prim +Exports: + +Re-Exports: + +Foreign: + +Declarations: diff --git a/tests/purus/passing/RedefinedFixity/output/M3/externs.cbor b/tests/purus/passing/RedefinedFixity/output/M3/externs.cbor new file mode 100644 index 000000000..ad234ae5c Binary files /dev/null and b/tests/purus/passing/RedefinedFixity/output/M3/externs.cbor differ diff --git a/tests/purus/passing/RedefinedFixity/output/M3/index.cfn b/tests/purus/passing/RedefinedFixity/output/M3/index.cfn new file mode 100644 index 000000000..bc0bfba76 --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/output/M3/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[],"exports":[],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,10],"start":[3,1]}},"moduleName":["M1"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,1]}},"moduleName":["M2"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["M3"],"modulePath":"tests/purus/passing/RedefinedFixity/M3.purs","reExports":{},"sourceSpan":{"end":[4,10],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/RedefinedFixity/output/M3/index.cfn.pretty b/tests/purus/passing/RedefinedFixity/output/M3/index.cfn.pretty new file mode 100644 index 000000000..f0152549f --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/output/M3/index.cfn.pretty @@ -0,0 +1,13 @@ +M3 (tests/purus/passing/RedefinedFixity/M3.purs) +Imported Modules: + Builtin, + M1, + M2, + Prim +Exports: + +Re-Exports: + +Foreign: + +Declarations: diff --git a/tests/purus/passing/RedefinedFixity/output/Main/externs.cbor b/tests/purus/passing/RedefinedFixity/output/Main/externs.cbor new file mode 100644 index 000000000..1a1c0ed65 Binary files /dev/null and b/tests/purus/passing/RedefinedFixity/output/Main/externs.cbor differ diff --git a/tests/purus/passing/RedefinedFixity/output/Main/index.cfn b/tests/purus/passing/RedefinedFixity/output/Main/index.cfn new file mode 100644 index 000000000..100939f25 --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/output/Main/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,14],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,14],"start":[5,8]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"Done"}},"identifier":"main"}],"exports":["main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,14],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[3,10],"start":[3,1]}},"moduleName":["M3"]},{"annotation":{"meta":null,"sourceSpan":{"end":[5,14],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Main"],"modulePath":"tests/purus/passing/RedefinedFixity/RedefinedFixity.purs","reExports":{},"sourceSpan":{"end":[5,14],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/RedefinedFixity/output/Main/index.cfn.pretty b/tests/purus/passing/RedefinedFixity/output/Main/index.cfn.pretty new file mode 100644 index 000000000..ed4ca6019 --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/output/Main/index.cfn.pretty @@ -0,0 +1,14 @@ +Main (tests/purus/passing/RedefinedFixity/RedefinedFixity.purs) +Imported Modules: + Builtin, + M3, + Prim +Exports: + main +Re-Exports: + +Foreign: + +Declarations: +main :: String +main = ("Done": String) \ No newline at end of file diff --git a/tests/purus/passing/RedefinedFixity/output/package.json b/tests/purus/passing/RedefinedFixity/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/RedefinedFixity/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict/A.purs b/tests/purus/passing/ResolvableScopeConflict/A.purs new file mode 100644 index 000000000..302b0328d --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict/A.purs @@ -0,0 +1,4 @@ +module A where + +thing :: Int +thing = 1 diff --git a/tests/purus/passing/ResolvableScopeConflict/B.purs b/tests/purus/passing/ResolvableScopeConflict/B.purs new file mode 100644 index 000000000..4ad4bb6f4 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict/B.purs @@ -0,0 +1,7 @@ +module B where + +thing :: Int +thing = 2 + +zing :: Int +zing = 3 diff --git a/tests/purus/passing/ResolvableScopeConflict/ResolvableScopeConflict.purs b/tests/purus/passing/ResolvableScopeConflict/ResolvableScopeConflict.purs new file mode 100644 index 000000000..aa2bed42e --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict/ResolvableScopeConflict.purs @@ -0,0 +1,12 @@ +module Main where + +import A (thing) +import B + +-- Not an error as although we have `thing` in scope from both A and B, it is +-- imported explicitly from A, giving it a resolvable solution. +what :: Boolean -> Int +what true = thing +what false = zing + +main = "Done" diff --git a/tests/purus/passing/ResolvableScopeConflict/output/A/externs.cbor b/tests/purus/passing/ResolvableScopeConflict/output/A/externs.cbor new file mode 100644 index 000000000..d4c464582 Binary files /dev/null and b/tests/purus/passing/ResolvableScopeConflict/output/A/externs.cbor differ diff --git a/tests/purus/passing/ResolvableScopeConflict/output/A/index.cfn b/tests/purus/passing/ResolvableScopeConflict/output/A/index.cfn new file mode 100644 index 000000000..df5a6ef72 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict/output/A/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,13],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"identifier":"thing"}],"exports":["thing"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["A"],"modulePath":"tests/purus/passing/ResolvableScopeConflict/A.purs","reExports":{},"sourceSpan":{"end":[4,10],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict/output/A/index.cfn.pretty b/tests/purus/passing/ResolvableScopeConflict/output/A/index.cfn.pretty new file mode 100644 index 000000000..34b172e24 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict/output/A/index.cfn.pretty @@ -0,0 +1,13 @@ +A (tests/purus/passing/ResolvableScopeConflict/A.purs) +Imported Modules: + Builtin, + Prim +Exports: + thing +Re-Exports: + +Foreign: + +Declarations: +thing :: Int +thing = (1: Int) \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict/output/B/externs.cbor b/tests/purus/passing/ResolvableScopeConflict/output/B/externs.cbor new file mode 100644 index 000000000..9d7aa5caa Binary files /dev/null and b/tests/purus/passing/ResolvableScopeConflict/output/B/externs.cbor differ diff --git a/tests/purus/passing/ResolvableScopeConflict/output/B/index.cfn b/tests/purus/passing/ResolvableScopeConflict/output/B/index.cfn new file mode 100644 index 000000000..2b67756c1 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict/output/B/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,12],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,9],"start":[7,8]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":3}},"identifier":"zing"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,13],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"identifier":"thing"}],"exports":["thing","zing"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[7,9],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,9],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["B"],"modulePath":"tests/purus/passing/ResolvableScopeConflict/B.purs","reExports":{},"sourceSpan":{"end":[7,9],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict/output/B/index.cfn.pretty b/tests/purus/passing/ResolvableScopeConflict/output/B/index.cfn.pretty new file mode 100644 index 000000000..87b8b09d6 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict/output/B/index.cfn.pretty @@ -0,0 +1,17 @@ +B (tests/purus/passing/ResolvableScopeConflict/B.purs) +Imported Modules: + Builtin, + Prim +Exports: + thing, + zing +Re-Exports: + +Foreign: + +Declarations: +zing :: Int +zing = (3: Int) + +thing :: Int +thing = (2: Int) \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict/output/Main/externs.cbor b/tests/purus/passing/ResolvableScopeConflict/output/Main/externs.cbor new file mode 100644 index 000000000..3da785733 Binary files /dev/null and b/tests/purus/passing/ResolvableScopeConflict/output/Main/externs.cbor differ diff --git a/tests/purus/passing/ResolvableScopeConflict/output/Main/index.cfn b/tests/purus/passing/ResolvableScopeConflict/output/Main/index.cfn new file mode 100644 index 000000000..999c05a00 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict/output/Main/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[8,23],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[9,10],"start":[9,6]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[9,18],"start":[9,13]}},"kind":"Var","type":{"annotation":[{"end":[3,13],"name":"tests/purus/passing/ResolvableScopeConflict/A.purs","start":[3,10]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"thing","moduleName":["A"]}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[10,11],"start":[10,6]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":false}}],"expression":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[10,18],"start":[10,14]}},"kind":"Var","type":{"annotation":[{"end":[6,12],"name":"tests/purus/passing/ResolvableScopeConflict/B.purs","start":[6,9]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"zing","moduleName":["B"]}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[9,18],"start":[9,1]}},"kind":"Var","type":{"annotation":[{"end":[8,16],"name":"tests/purus/passing/ResolvableScopeConflict/ResolvableScopeConflict.purs","start":[8,9]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"identifier":"v","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[8,23],"name":"tests/purus/passing/ResolvableScopeConflict/ResolvableScopeConflict.purs","start":[8,20]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,16],"name":"tests/purus/passing/ResolvableScopeConflict/ResolvableScopeConflict.purs","start":[8,9]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,23],"name":"tests/purus/passing/ResolvableScopeConflict/ResolvableScopeConflict.purs","start":[8,20]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"what"},{"annotation":{"meta":null,"sourceSpan":{"end":[12,14],"start":[12,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[12,14],"start":[12,8]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"Done"}},"identifier":"main"}],"exports":["what","main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[12,14],"start":[1,1]}},"moduleName":["A"]},{"annotation":{"meta":null,"sourceSpan":{"end":[12,14],"start":[1,1]}},"moduleName":["B"]},{"annotation":{"meta":null,"sourceSpan":{"end":[12,14],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[12,14],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Main"],"modulePath":"tests/purus/passing/ResolvableScopeConflict/ResolvableScopeConflict.purs","reExports":{},"sourceSpan":{"end":[12,14],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict/output/Main/index.cfn.pretty b/tests/purus/passing/ResolvableScopeConflict/output/Main/index.cfn.pretty new file mode 100644 index 000000000..9128b3062 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict/output/Main/index.cfn.pretty @@ -0,0 +1,23 @@ +Main (tests/purus/passing/ResolvableScopeConflict/ResolvableScopeConflict.purs) +Imported Modules: + A, + B, + Builtin, + Prim +Exports: + what, + main +Re-Exports: + +Foreign: + +Declarations: +what :: Boolean -> Int +what = + \(v: Boolean) -> + case (v: Boolean) of + true -> (thing: Int) + false -> (zing: Int) + +main :: String +main = ("Done": String) \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict/output/package.json b/tests/purus/passing/ResolvableScopeConflict/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict2/A.purs b/tests/purus/passing/ResolvableScopeConflict2/A.purs new file mode 100644 index 000000000..943011cd7 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict2/A.purs @@ -0,0 +1,7 @@ +module A where + +thing :: Int +thing = 2 + +zing :: Int +zing = 3 diff --git a/tests/purus/passing/ResolvableScopeConflict2/ResolvableScopeConflict2.purs b/tests/purus/passing/ResolvableScopeConflict2/ResolvableScopeConflict2.purs new file mode 100644 index 000000000..899fadecb --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict2/ResolvableScopeConflict2.purs @@ -0,0 +1,14 @@ +module Main where + +import A + +thing :: Int +thing = 1 + +-- Not an error as although we have `thing` in scope from both Main and A, +-- as the local declaration takes precedence over the implicit import +what :: Boolean -> Int +what true = thing +what false = zing + +main = "Done" diff --git a/tests/purus/passing/ResolvableScopeConflict2/output/A/externs.cbor b/tests/purus/passing/ResolvableScopeConflict2/output/A/externs.cbor new file mode 100644 index 000000000..70fb0c764 Binary files /dev/null and b/tests/purus/passing/ResolvableScopeConflict2/output/A/externs.cbor differ diff --git a/tests/purus/passing/ResolvableScopeConflict2/output/A/index.cfn b/tests/purus/passing/ResolvableScopeConflict2/output/A/index.cfn new file mode 100644 index 000000000..8b42a20c9 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict2/output/A/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,12],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,9],"start":[7,8]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":3}},"identifier":"zing"},{"annotation":{"meta":null,"sourceSpan":{"end":[3,13],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"identifier":"thing"}],"exports":["thing","zing"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[7,9],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,9],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["A"],"modulePath":"tests/purus/passing/ResolvableScopeConflict2/A.purs","reExports":{},"sourceSpan":{"end":[7,9],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict2/output/A/index.cfn.pretty b/tests/purus/passing/ResolvableScopeConflict2/output/A/index.cfn.pretty new file mode 100644 index 000000000..1863f79fe --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict2/output/A/index.cfn.pretty @@ -0,0 +1,17 @@ +A (tests/purus/passing/ResolvableScopeConflict2/A.purs) +Imported Modules: + Builtin, + Prim +Exports: + thing, + zing +Re-Exports: + +Foreign: + +Declarations: +zing :: Int +zing = (3: Int) + +thing :: Int +thing = (2: Int) \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict2/output/Main/externs.cbor b/tests/purus/passing/ResolvableScopeConflict2/output/Main/externs.cbor new file mode 100644 index 000000000..91647003e Binary files /dev/null and b/tests/purus/passing/ResolvableScopeConflict2/output/Main/externs.cbor differ diff --git a/tests/purus/passing/ResolvableScopeConflict2/output/Main/index.cfn b/tests/purus/passing/ResolvableScopeConflict2/output/Main/index.cfn new file mode 100644 index 000000000..649fee22e --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict2/output/Main/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,13],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,10],"start":[6,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"identifier":"thing"},{"annotation":{"meta":null,"sourceSpan":{"end":[10,23],"start":[10,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[11,10],"start":[11,6]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":true}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[11,18],"start":[11,13]}},"kind":"Var","type":{"annotation":[{"end":[5,13],"name":"tests/purus/passing/ResolvableScopeConflict2/ResolvableScopeConflict2.purs","start":[5,10]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"thing","moduleName":["Main"]}},"isGuarded":false},{"binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[12,11],"start":[12,6]}},"binderType":"LiteralBinder","literal":{"literalType":"BooleanLiteral","value":false}}],"expression":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[12,18],"start":[12,14]}},"kind":"Var","type":{"annotation":[{"end":[6,12],"name":"tests/purus/passing/ResolvableScopeConflict2/A.purs","start":[6,9]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"identifier":"zing","moduleName":["A"]}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[11,18],"start":[11,1]}},"kind":"Var","type":{"annotation":[{"end":[10,16],"name":"tests/purus/passing/ResolvableScopeConflict2/ResolvableScopeConflict2.purs","start":[10,9]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"},"value":{"identifier":"v","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[10,23],"name":"tests/purus/passing/ResolvableScopeConflict2/ResolvableScopeConflict2.purs","start":[10,20]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[10,16],"name":"tests/purus/passing/ResolvableScopeConflict2/ResolvableScopeConflict2.purs","start":[10,9]},[]],"contents":[["Prim"],"Boolean"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[10,23],"name":"tests/purus/passing/ResolvableScopeConflict2/ResolvableScopeConflict2.purs","start":[10,20]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"what"},{"annotation":{"meta":null,"sourceSpan":{"end":[14,14],"start":[14,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[14,14],"start":[14,8]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"Done"}},"identifier":"main"}],"exports":["thing","what","main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[14,14],"start":[1,1]}},"moduleName":["A"]},{"annotation":{"meta":null,"sourceSpan":{"end":[14,14],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[14,14],"start":[1,1]}},"moduleName":["Main"]},{"annotation":{"meta":null,"sourceSpan":{"end":[14,14],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Main"],"modulePath":"tests/purus/passing/ResolvableScopeConflict2/ResolvableScopeConflict2.purs","reExports":{},"sourceSpan":{"end":[14,14],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict2/output/Main/index.cfn.pretty b/tests/purus/passing/ResolvableScopeConflict2/output/Main/index.cfn.pretty new file mode 100644 index 000000000..3e02f0820 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict2/output/Main/index.cfn.pretty @@ -0,0 +1,27 @@ +Main (tests/purus/passing/ResolvableScopeConflict2/ResolvableScopeConflict2.purs) +Imported Modules: + A, + Builtin, + Main, + Prim +Exports: + thing, + what, + main +Re-Exports: + +Foreign: + +Declarations: +thing :: Int +thing = (1: Int) + +what :: Boolean -> Int +what = + \(v: Boolean) -> + case (v: Boolean) of + true -> (thing: Int) + false -> (zing: Int) + +main :: String +main = ("Done": String) \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict2/output/package.json b/tests/purus/passing/ResolvableScopeConflict2/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict2/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict3/A.purs b/tests/purus/passing/ResolvableScopeConflict3/A.purs new file mode 100644 index 000000000..302b0328d --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict3/A.purs @@ -0,0 +1,4 @@ +module A where + +thing :: Int +thing = 1 diff --git a/tests/purus/passing/ResolvableScopeConflict3/ResolvableScopeConflict3.purs b/tests/purus/passing/ResolvableScopeConflict3/ResolvableScopeConflict3.purs new file mode 100644 index 000000000..204008202 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict3/ResolvableScopeConflict3.purs @@ -0,0 +1,9 @@ +module Main (thing, main, module A) where + +import A + + +thing :: Int +thing = 2 + +main = "Done" diff --git a/tests/purus/passing/ResolvableScopeConflict3/output/A/externs.cbor b/tests/purus/passing/ResolvableScopeConflict3/output/A/externs.cbor new file mode 100644 index 000000000..759d25761 Binary files /dev/null and b/tests/purus/passing/ResolvableScopeConflict3/output/A/externs.cbor differ diff --git a/tests/purus/passing/ResolvableScopeConflict3/output/A/index.cfn b/tests/purus/passing/ResolvableScopeConflict3/output/A/index.cfn new file mode 100644 index 000000000..84959746e --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict3/output/A/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,13],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[4,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":1}},"identifier":"thing"}],"exports":["thing"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[4,10],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["A"],"modulePath":"tests/purus/passing/ResolvableScopeConflict3/A.purs","reExports":{},"sourceSpan":{"end":[4,10],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict3/output/A/index.cfn.pretty b/tests/purus/passing/ResolvableScopeConflict3/output/A/index.cfn.pretty new file mode 100644 index 000000000..5d2f6a759 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict3/output/A/index.cfn.pretty @@ -0,0 +1,13 @@ +A (tests/purus/passing/ResolvableScopeConflict3/A.purs) +Imported Modules: + Builtin, + Prim +Exports: + thing +Re-Exports: + +Foreign: + +Declarations: +thing :: Int +thing = (1: Int) \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict3/output/Main/externs.cbor b/tests/purus/passing/ResolvableScopeConflict3/output/Main/externs.cbor new file mode 100644 index 000000000..8c85d5848 Binary files /dev/null and b/tests/purus/passing/ResolvableScopeConflict3/output/Main/externs.cbor differ diff --git a/tests/purus/passing/ResolvableScopeConflict3/output/Main/index.cfn b/tests/purus/passing/ResolvableScopeConflict3/output/Main/index.cfn new file mode 100644 index 000000000..073d47237 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict3/output/Main/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,13],"start":[6,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[7,10],"start":[7,9]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Int"],"tag":"TypeConstructor"},"value":{"literalType":"IntLiteral","value":2}},"identifier":"thing"},{"annotation":{"meta":null,"sourceSpan":{"end":[9,14],"start":[9,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[9,14],"start":[9,8]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"Done"}},"identifier":"main"}],"exports":["thing","main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,9],"start":[3,1]}},"moduleName":["A"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,14],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,14],"start":[1,1]}},"moduleName":["Prim"]}],"moduleName":["Main"],"modulePath":"tests/purus/passing/ResolvableScopeConflict3/ResolvableScopeConflict3.purs","reExports":{},"sourceSpan":{"end":[9,14],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict3/output/Main/index.cfn.pretty b/tests/purus/passing/ResolvableScopeConflict3/output/Main/index.cfn.pretty new file mode 100644 index 000000000..6d4747a8c --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict3/output/Main/index.cfn.pretty @@ -0,0 +1,18 @@ +Main (tests/purus/passing/ResolvableScopeConflict3/ResolvableScopeConflict3.purs) +Imported Modules: + A, + Builtin, + Prim +Exports: + thing, + main +Re-Exports: + +Foreign: + +Declarations: +thing :: Int +thing = (2: Int) + +main :: String +main = ("Done": String) \ No newline at end of file diff --git a/tests/purus/passing/ResolvableScopeConflict3/output/package.json b/tests/purus/passing/ResolvableScopeConflict3/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ResolvableScopeConflict3/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/ShadowedModuleName/ShadowedModuleName.purs b/tests/purus/passing/ShadowedModuleName/ShadowedModuleName.purs new file mode 100644 index 000000000..80061b5fb --- /dev/null +++ b/tests/purus/passing/ShadowedModuleName/ShadowedModuleName.purs @@ -0,0 +1,7 @@ +module Main where + +import Test + +data Test = Test + +main = runZ (Z "Done") diff --git a/tests/purus/passing/ShadowedModuleName/Test.purs b/tests/purus/passing/ShadowedModuleName/Test.purs new file mode 100644 index 000000000..b30eb2dfd --- /dev/null +++ b/tests/purus/passing/ShadowedModuleName/Test.purs @@ -0,0 +1,6 @@ +module Test where + +data Z = Z String + +runZ :: Z -> String +runZ (Z s) = s diff --git a/tests/purus/passing/ShadowedModuleName/output/Main/externs.cbor b/tests/purus/passing/ShadowedModuleName/output/Main/externs.cbor new file mode 100644 index 000000000..da41f81da Binary files /dev/null and b/tests/purus/passing/ShadowedModuleName/output/Main/externs.cbor differ diff --git a/tests/purus/passing/ShadowedModuleName/output/Main/index.cfn b/tests/purus/passing/ShadowedModuleName/output/Main/index.cfn new file mode 100644 index 000000000..a8525237a --- /dev/null +++ b/tests/purus/passing/ShadowedModuleName/output/Main/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"Test":["data",[],[{"dataCtorAnn":[{"end":[5,17],"name":"tests/purus/passing/ShadowedModuleName/ShadowedModuleName.purs","start":[5,11]},[]],"dataCtorFields":[],"dataCtorName":"Test"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,17],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[5,17],"start":[5,1]}},"constructorName":"Test","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Main"],"Test"],"tag":"TypeConstructor"},"typeName":"Test"},"identifier":"Test"},{"annotation":{"meta":null,"sourceSpan":{"end":[7,23],"start":[7,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[7,12],"start":[7,8]}},"kind":"Var","type":{"annotation":[{"end":[5,20],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[5,9]},[]],"contents":[{"annotation":[{"end":[5,20],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[5,9]},[]],"contents":[{"annotation":[{"end":[5,13],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[5,11]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[5,10],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[5,9]},[]],"contents":[["Test"],"Z"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[5,20],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[5,14]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"runZ","moduleName":["Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[7,23],"start":[7,8]}},"argument":{"abstraction":{"annotation":{"meta":{"constructorType":"ProductType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[7,15],"start":[7,14]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,18],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[3,12]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Test"],"Z"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"Z","moduleName":["Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[7,22],"start":[7,14]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[7,22],"start":[7,16]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"literalType":"StringLiteral","value":"Done"}},"kind":"App"},"kind":"App"},"identifier":"main"}],"exports":["Test","main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[7,23],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,23],"start":[1,1]}},"moduleName":["Prim"]},{"annotation":{"meta":null,"sourceSpan":{"end":[7,23],"start":[1,1]}},"moduleName":["Test"]}],"moduleName":["Main"],"modulePath":"tests/purus/passing/ShadowedModuleName/ShadowedModuleName.purs","reExports":{},"sourceSpan":{"end":[7,23],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ShadowedModuleName/output/Main/index.cfn.pretty b/tests/purus/passing/ShadowedModuleName/output/Main/index.cfn.pretty new file mode 100644 index 000000000..31146dded --- /dev/null +++ b/tests/purus/passing/ShadowedModuleName/output/Main/index.cfn.pretty @@ -0,0 +1,18 @@ +Main (tests/purus/passing/ShadowedModuleName/ShadowedModuleName.purs) +Imported Modules: + Builtin, + Prim, + Test +Exports: + Test, + main +Re-Exports: + +Foreign: + +Declarations: +Test :: Test +Test = Test + +main :: String +main = (runZ: Z -> String) ((Z: String -> Z) ("Done": String)) \ No newline at end of file diff --git a/tests/purus/passing/ShadowedModuleName/output/Test/externs.cbor b/tests/purus/passing/ShadowedModuleName/output/Test/externs.cbor new file mode 100644 index 000000000..c7ed3b4b0 Binary files /dev/null and b/tests/purus/passing/ShadowedModuleName/output/Test/externs.cbor differ diff --git a/tests/purus/passing/ShadowedModuleName/output/Test/index.cfn b/tests/purus/passing/ShadowedModuleName/output/Test/index.cfn new file mode 100644 index 000000000..e8faaded6 --- /dev/null +++ b/tests/purus/passing/ShadowedModuleName/output/Test/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"Z":["data",[],[{"dataCtorAnn":[{"end":[3,11],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[3,8]},[]],"dataCtorFields":[[{"Ident":"value0"},{"annotation":[{"end":[3,18],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[3,12]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}]],"dataCtorName":"Z"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,18],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,18],"start":[3,1]}},"constructorName":"Z","fieldNames":["value0"],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[3,18],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[3,12]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Test"],"Z"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"typeName":"Z"},"identifier":"Z"},{"annotation":{"meta":null,"sourceSpan":{"end":[5,20],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"v","body":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"constructorType":"ProductType","identifiers":["value0"],"metaType":"IsConstructor"},"sourceSpan":{"end":[6,10],"start":[6,7]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,10],"start":[6,9]}},"binderType":"VarBinder","identifier":"s"}],"constructorName":{"identifier":"Z","moduleName":["Test"]},"typeName":{"identifier":"Z","moduleName":["Test"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,15],"start":[6,14]}},"kind":"Var","type":{"annotation":[{"end":[3,18],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[3,12]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"},"value":{"identifier":"s","sourcePos":[6,9]}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,15],"start":[6,1]}},"kind":"Var","type":{"annotation":[{"end":[5,10],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[5,9]},[]],"contents":[["Test"],"Z"],"tag":"TypeConstructor"},"value":{"identifier":"v","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[5,20],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[5,14]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[5,10],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[5,9]},[]],"contents":[["Test"],"Z"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[5,20],"name":"tests/purus/passing/ShadowedModuleName/Test.purs","start":[5,14]},[]],"contents":[["Prim"],"String"],"tag":"TypeConstructor"}],"tag":"TypeApp"}},"identifier":"runZ"}],"exports":["Z","runZ"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,15],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,15],"start":[1,1]}},"moduleName":["Prim"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,15],"start":[1,1]}},"moduleName":["Test"]}],"moduleName":["Test"],"modulePath":"tests/purus/passing/ShadowedModuleName/Test.purs","reExports":{},"sourceSpan":{"end":[6,15],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/ShadowedModuleName/output/Test/index.cfn.pretty b/tests/purus/passing/ShadowedModuleName/output/Test/index.cfn.pretty new file mode 100644 index 000000000..cd32dc20e --- /dev/null +++ b/tests/purus/passing/ShadowedModuleName/output/Test/index.cfn.pretty @@ -0,0 +1,21 @@ +Test (tests/purus/passing/ShadowedModuleName/Test.purs) +Imported Modules: + Builtin, + Prim, + Test +Exports: + Z, + runZ +Re-Exports: + +Foreign: + +Declarations: +Z :: String -> Z +Z = Z + +runZ :: Z -> String +runZ = + \(v: Z) -> + case (v: Z) of + Z s -> (s: String) \ No newline at end of file diff --git a/tests/purus/passing/ShadowedModuleName/output/package.json b/tests/purus/passing/ShadowedModuleName/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/ShadowedModuleName/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/tests/purus/passing/TransitiveImport/Middle.purs b/tests/purus/passing/TransitiveImport/Middle.purs new file mode 100644 index 000000000..57e2a2b10 --- /dev/null +++ b/tests/purus/passing/TransitiveImport/Middle.purs @@ -0,0 +1,9 @@ +module Middle (module Test, unit, middle) where + +import Test + +unit :: Unit +unit = Unit + +middle :: forall a. TestCls a => a -> a +middle = test diff --git a/tests/purus/passing/TransitiveImport/Test.purs b/tests/purus/passing/TransitiveImport/Test.purs new file mode 100644 index 000000000..2d735b509 --- /dev/null +++ b/tests/purus/passing/TransitiveImport/Test.purs @@ -0,0 +1,9 @@ +module Test where + +data Unit = Unit + +class TestCls a where + test :: a -> a + +instance unitTestCls :: TestCls Unit where + test _ = Unit diff --git a/tests/purus/passing/TransitiveImport/TransitiveImport.purs b/tests/purus/passing/TransitiveImport/TransitiveImport.purs new file mode 100644 index 000000000..5d7ad43c4 --- /dev/null +++ b/tests/purus/passing/TransitiveImport/TransitiveImport.purs @@ -0,0 +1,6 @@ +module Main where + + import Middle + + main :: Unit + main = (middle unit) diff --git a/tests/purus/passing/TransitiveImport/output/Main/externs.cbor b/tests/purus/passing/TransitiveImport/output/Main/externs.cbor new file mode 100644 index 000000000..aa2d9df77 Binary files /dev/null and b/tests/purus/passing/TransitiveImport/output/Main/externs.cbor differ diff --git a/tests/purus/passing/TransitiveImport/output/Main/index.cfn b/tests/purus/passing/TransitiveImport/output/Main/index.cfn new file mode 100644 index 000000000..ad16ca49c --- /dev/null +++ b/tests/purus/passing/TransitiveImport/output/Main/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,15],"start":[5,3]}},"bindType":"NonRec","expression":{"abstraction":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[6,18],"start":[6,12]}},"kind":"Var","type":{"annotation":[{"end":[8,40],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,11]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[8,30],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,21]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":0,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Test"],"TestCls$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,30],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,29]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[8,40],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,34]},[]],"contents":[{"annotation":[{"end":[8,40],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,34]},[]],"contents":[{"annotation":[{"end":[8,38],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,36]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,35],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,34]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[8,40],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,39]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"},"value":{"identifier":"middle","moduleName":["Middle"]}},"annotation":{"meta":null,"sourceSpan":{"end":[6,23],"start":[6,12]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Test"],"TestCls$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,37],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[8,33]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"}],"tag":"TypeApp"},"value":{"identifier":"unitTestCls","moduleName":["Test"]}},"kind":"App"},"annotation":{"meta":null,"sourceSpan":{"end":[6,23],"start":[6,12]}},"argument":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[6,23],"start":[6,19]}},"kind":"Var","type":{"annotation":[{"end":[5,13],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[5,9]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"},"value":{"identifier":"unit","moduleName":["Middle"]}},"kind":"App"},"identifier":"main"}],"exports":["main"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,24],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,24],"start":[1,1]}},"moduleName":["Middle"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,24],"start":[1,1]}},"moduleName":["Prim"]},{"annotation":{"meta":null,"sourceSpan":{"end":[6,24],"start":[1,1]}},"moduleName":["Test"]}],"moduleName":["Main"],"modulePath":"tests/purus/passing/TransitiveImport/TransitiveImport.purs","reExports":{},"sourceSpan":{"end":[6,24],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/TransitiveImport/output/Main/index.cfn.pretty b/tests/purus/passing/TransitiveImport/output/Main/index.cfn.pretty new file mode 100644 index 000000000..489c6ce9f --- /dev/null +++ b/tests/purus/passing/TransitiveImport/output/Main/index.cfn.pretty @@ -0,0 +1,18 @@ +Main (tests/purus/passing/TransitiveImport/TransitiveImport.purs) +Imported Modules: + Builtin, + Middle, + Prim, + Test +Exports: + main +Re-Exports: + +Foreign: + +Declarations: +main :: Unit +main = + (middle: forall (a :: Type). TestCls$Dict a -> a -> a) + (unitTestCls: TestCls$Dict Unit) + (unit: Unit) \ No newline at end of file diff --git a/tests/purus/passing/TransitiveImport/output/Middle/externs.cbor b/tests/purus/passing/TransitiveImport/output/Middle/externs.cbor new file mode 100644 index 000000000..f7167399a Binary files /dev/null and b/tests/purus/passing/TransitiveImport/output/Middle/externs.cbor differ diff --git a/tests/purus/passing/TransitiveImport/output/Middle/index.cfn b/tests/purus/passing/TransitiveImport/output/Middle/index.cfn new file mode 100644 index 000000000..b06962de1 --- /dev/null +++ b/tests/purus/passing/TransitiveImport/output/Middle/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[5,13],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"constructorType":"ProductType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[6,12],"start":[6,8]}},"kind":"Var","type":{"annotation":[{"end":[5,13],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[5,9]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"},"value":{"identifier":"Unit","moduleName":["Test"]}},"identifier":"unit"},{"annotation":{"meta":null,"sourceSpan":{"end":[8,40],"start":[8,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"argument":"dictTestCls","body":{"abstraction":{"annotation":{"meta":{"metaType":"IsForeign"},"sourceSpan":{"end":[9,14],"start":[9,10]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":1,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Test"],"TestCls$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,12],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,16]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"},"value":{"identifier":"test","moduleName":["Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[9,14],"start":[9,10]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[0,0],"start":[0,0]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Test"],"TestCls$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,30],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,29]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"dictTestCls","sourcePos":[0,0]}},"kind":"App"},"kind":"Abs","type":{"annotation":[{"end":[8,40],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,11]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[8,30],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,21]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":0,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Test"],"TestCls$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,30],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,29]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[8,40],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,34]},[]],"contents":[{"annotation":[{"end":[8,40],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,34]},[]],"contents":[{"annotation":[{"end":[8,38],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,36]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,35],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,34]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[8,40],"name":"tests/purus/passing/TransitiveImport/Middle.purs","start":[8,39]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"middle"}],"exports":["unit","middle"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[9,14],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,14],"start":[1,1]}},"moduleName":["Prim"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,14],"start":[1,1]}},"moduleName":["Test"]}],"moduleName":["Middle"],"modulePath":"tests/purus/passing/TransitiveImport/Middle.purs","reExports":{"Test":["Unit","test"]},"sourceSpan":{"end":[9,14],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/TransitiveImport/output/Middle/index.cfn.pretty b/tests/purus/passing/TransitiveImport/output/Middle/index.cfn.pretty new file mode 100644 index 000000000..b9c49ab73 --- /dev/null +++ b/tests/purus/passing/TransitiveImport/output/Middle/index.cfn.pretty @@ -0,0 +1,22 @@ +Middle (tests/purus/passing/TransitiveImport/Middle.purs) +Imported Modules: + Builtin, + Prim, + Test +Exports: + unit, + middle +Re-Exports: + Test.Unit + Test.test +Foreign: + +Declarations: +unit :: Unit +unit = (Unit: Unit) + +middle :: forall (a :: Type). TestCls$Dict a -> a -> a +middle = + \(dictTestCls: TestCls$Dict a) -> + (test: forall (@a :: Type). TestCls$Dict a -> a -> a) + (dictTestCls: TestCls$Dict a) \ No newline at end of file diff --git a/tests/purus/passing/TransitiveImport/output/Test/externs.cbor b/tests/purus/passing/TransitiveImport/output/Test/externs.cbor new file mode 100644 index 000000000..0432094b7 Binary files /dev/null and b/tests/purus/passing/TransitiveImport/output/Test/externs.cbor differ diff --git a/tests/purus/passing/TransitiveImport/output/Test/index.cfn b/tests/purus/passing/TransitiveImport/output/Test/index.cfn new file mode 100644 index 000000000..c347529a3 --- /dev/null +++ b/tests/purus/passing/TransitiveImport/output/Test/index.cfn @@ -0,0 +1 @@ +{"builtWith":"0.0.1","comments":[],"dataTypes":{"TestCls$Dict":["newtype",[["a",null]],[{"dataCtorAnn":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[5,1]},[]],"dataCtorFields":[[{"Ident":"dict"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["test",{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,12],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,16]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}]],"dataCtorName":"TestCls$Dict"}]],"Unit":["data",[],[{"dataCtorAnn":[{"end":[3,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[3,11]},[]],"dataCtorFields":[],"dataCtorName":"Unit"}]]},"decls":[{"annotation":{"meta":null,"sourceSpan":{"end":[3,17],"start":[3,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[3,17],"start":[3,1]}},"constructorName":"Unit","fieldNames":[],"kind":"Constructor","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"},"typeName":"Unit"},"identifier":"Unit"},{"annotation":{"meta":{"metaType":"IsTypeClassConstructor"},"sourceSpan":{"end":[6,17],"start":[5,1]}},"bindType":"NonRec","expression":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[6,17],"start":[5,1]}},"argument":"x","body":{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[5,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["test",{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,12],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,16]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"x","sourcePos":[0,0]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":null,"skolem":null,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["test",{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,12],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,16]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["test",{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,12],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,16]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarInvisible"},"tag":"ForAll"}},"identifier":"TestCls$Dict"},{"annotation":{"meta":null,"sourceSpan":{"end":[9,16],"start":[8,1]}},"bindType":"NonRec","expression":{"abstraction":{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[9,16],"start":[8,1]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["test",{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,37],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[8,33]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,37],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[8,33]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Test"],"TestCls$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,37],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[8,33]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"}],"tag":"TypeApp"}],"tag":"TypeApp"},"value":{"identifier":"TestCls$Dict","moduleName":["Test"]}},"annotation":{"meta":null,"sourceSpan":{"end":[9,16],"start":[8,1]}},"argument":{"annotation":{"meta":null,"sourceSpan":{"end":[9,16],"start":[8,1]}},"kind":"Literal","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["test",{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,37],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[8,33]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,37],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[8,33]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"literalType":"ObjectLiteral","value":[["test",{"annotation":{"meta":null,"sourceSpan":{"end":[9,16],"start":[9,3]}},"argument":"v","body":{"annotation":{"meta":{"constructorType":"ProductType","identifiers":[],"metaType":"IsConstructor"},"sourceSpan":{"end":[9,16],"start":[9,12]}},"kind":"Var","type":{"annotation":[{"end":[8,37],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[8,33]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"},"value":{"identifier":"Unit","moduleName":["Test"]}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[8,37],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[8,33]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"}],"tag":"TypeApp"},{"annotation":[{"end":[8,37],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[8,33]},[]],"contents":[["Test"],"Unit"],"tag":"TypeConstructor"}],"tag":"TypeApp"}}]]}},"kind":"App"},"identifier":"unitTestCls"},{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[6,3]}},"bindType":"NonRec","expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[6,3]}},"argument":"dict","body":{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[6,3]}},"caseAlternatives":[{"binders":[{"annotation":{"meta":{"metaType":"IsNewtype"},"sourceSpan":{"end":[6,17],"start":[6,3]}},"binderType":"ConstructorBinder","binders":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[6,3]}},"binderType":"VarBinder","identifier":"v"}],"constructorName":{"identifier":"TestCls$Dict","moduleName":["Test"]},"typeName":{"identifier":"TestCls$Dict","moduleName":["Test"]}}],"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[6,3]}},"expression":{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[6,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Record"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":["test",{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"tag":"REmpty"},{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"}],"tag":"KindApp"}],"tag":"RCons"}],"tag":"TypeApp"},"value":{"identifier":"v","sourcePos":[6,3]}},"fieldName":"test","kind":"Accessor","type":{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,12],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,16]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}},"isGuarded":false}],"caseExpressions":[{"annotation":{"meta":null,"sourceSpan":{"end":[6,17],"start":[6,3]}},"kind":"Var","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Test"],"TestCls$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},"value":{"identifier":"dict","sourcePos":[0,0]}}],"kind":"Case","type":{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,12],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,16]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}},"kind":"Abs","type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":{"identifier":"a","kind":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Type"],"tag":"TypeConstructor"},"skolem":1,"type":{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":[["Test"],"TestCls$Dict"],"tag":"TypeConstructor"},{"annotation":[{"end":[0,0],"name":"","start":[0,0]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":[{"annotation":[{"end":[6,15],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,13]},[]],"contents":[["Prim"],"Function"],"tag":"TypeConstructor"},{"annotation":[{"end":[6,12],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,11]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"},{"annotation":[{"end":[6,17],"name":"tests/purus/passing/TransitiveImport/Test.purs","start":[6,16]},[]],"contents":"a","tag":"TypeVar"}],"tag":"TypeApp"}],"tag":"TypeApp"},"visibility":"TypeVarVisible"},"tag":"ForAll"}},"identifier":"test"}],"exports":["test","Unit","unitTestCls"],"foreign":[],"imports":[{"annotation":{"meta":null,"sourceSpan":{"end":[9,16],"start":[1,1]}},"moduleName":["Builtin"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,16],"start":[1,1]}},"moduleName":["Prim"]},{"annotation":{"meta":null,"sourceSpan":{"end":[9,16],"start":[1,1]}},"moduleName":["Test"]}],"moduleName":["Test"],"modulePath":"tests/purus/passing/TransitiveImport/Test.purs","reExports":{},"sourceSpan":{"end":[9,16],"start":[1,1]}} \ No newline at end of file diff --git a/tests/purus/passing/TransitiveImport/output/Test/index.cfn.pretty b/tests/purus/passing/TransitiveImport/output/Test/index.cfn.pretty new file mode 100644 index 000000000..c9e4993c7 --- /dev/null +++ b/tests/purus/passing/TransitiveImport/output/Test/index.cfn.pretty @@ -0,0 +1,30 @@ +Test (tests/purus/passing/TransitiveImport/Test.purs) +Imported Modules: + Builtin, + Prim, + Test +Exports: + test, + Unit, + unitTestCls +Re-Exports: + +Foreign: + +Declarations: +Unit :: Unit +Unit = Unit + +TestCls$Dict :: forall a. { test :: a -> a } -> { test :: a -> a } +TestCls$Dict = \(x: { test :: a -> a }) -> (x: { test :: a -> a }) + +unitTestCls :: TestCls$Dict Unit +unitTestCls = + (TestCls$Dict: { test :: Unit -> Unit } -> TestCls$Dict Unit) + ({ test: \(v: Unit) -> (Unit: Unit) }: { test :: Unit -> Unit }) + +test :: forall (@a :: Type). TestCls$Dict a -> a -> a +test = + \(dict: TestCls$Dict a) -> + case (dict: TestCls$Dict a) of + TestCls$Dict v -> (v: { test :: a -> a }).test \ No newline at end of file diff --git a/tests/purus/passing/TransitiveImport/output/package.json b/tests/purus/passing/TransitiveImport/output/package.json new file mode 100644 index 000000000..7c34deb58 --- /dev/null +++ b/tests/purus/passing/TransitiveImport/output/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file