├── LICENSE ├── README.md ├── glossary.md ├── haskell-resources.md └── scripts └── types.rb /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Elm Community 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of elm-compiler-docs nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # elm-compiler-docs 2 | This guide is assembled by the Elm community, with no assistance from Elm's creator. It's a reverse engineering effort in progress. It's based on the 0.18 compiler. If you're new to Haskell or would appreciate a refresher, see [haskell-resources.md](haskell-resources.md) for some helpful resources and tutorials. 3 | 4 | ## Getting Started 5 | Haskell and Cabal can be a pain to set up, especially so for the Elm compiler 0.18, which uses an earlier version of Haskell. The easiest way to get the codebase running on your computer is through [Elm Env](https://github.com/breezykermo/elm-env), a Docker image that sets up a contained Haskell environment in a container. 6 | 7 | Once you have Elm Env up and running, navigate to `Elm-Platform/0.18`. From here you can build the compiler from source using the following commands: 8 | 9 | ```bash 10 | $ cabal install elm-compiler 11 | $ cabal install elm-make 12 | ``` 13 | 14 | These commands will build the compiler codebase. Note that, in order to keep the latest build in your path (inside the Docker container), you may have to run: 15 | 16 | ```bash 17 | $ export PATH=$PATH:/Elm-Package/Elm-Platform/0.18/.cabal-sandbox/bin 18 | ``` 19 | 20 | Alternatively the executables can be found at `/Elm-Package/Elm-Platform/0.18/.cabal-sandbox/bin`. 21 | 22 | ## elm-make 23 | 24 | [Elm-make](https://github.com/elm-lang/elm-make) is the command-line tool that manages and invokes the elm-compiler when it is processing a single file. The codebase is much smaller and less complex than elm-compiler, and as such it provides a handy entry point to understanding the Elm compiler in depth. 25 | 26 | There is a handy file in the elm-make source (the command-line tool that runs elm-compiler on a `.elm` file), called [TheMasterPlan.hs](https://github.com/elm-lang/elm-make/blob/master/src/TheMasterPlan.hs), that models each step in the build process, annotating the types of each intermediate representation. Evan has provided some helpful comments along the way that point to how each intermediate representation is generated, and what it is used for. The elm-make codebase provides the code for all the parts of 'the compiler' that we are familiar with--the CLI entry point, dependency crawling and aggregation, and the files that are generated as a result of the build. 27 | 28 | You can trace the points at which it enters the Elm compiler codebase in [Compile.hs](https://github.com/elm-lang/elm-make/blob/master/src/Pipeline/Compile.hs). I would recommend thoroughly wrapping your head around the data types and build process in elm-make before deep-diving into the elm-compiler code itself. 29 | 30 | ## How the compiler works 31 | The [entry point](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Compile.hs) of the compiler lists various passes over the source. (If you're new to compilers, read [this](https://github.com/thejameskyle/the-super-tiny-compiler).) 32 | 33 | * Parse the source code 34 | * Canonicalize all variables, pinning down where they came from 35 | * Run type inference 36 | * Nitpick (miscellaneous checks) 37 | * Optimization 38 | * Code generation 39 | 40 | The manager processes that run these phases can be found in the [Elm](https://github.com/elm-lang/elm-compiler/tree/master/src/Elm) directory. The entry point of the compiler is [Compiler.hs](https://github.com/elm-lang/elm-compiler/blob/master/src/Elm/Compiler.hs). 41 | 42 | The compile process happen inside the [Result](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Result.hs) type. This is like Elm's `Result` type but on steroids, with lots of places to put information about errors. It's also declared as a monad, which for our purposes makes it work well with chained operations (i.e. bail out if there are any errors), and allows the use of [do notation](https://en.wikibooks.org/wiki/Haskell/do_notation). If this doesn't make sense to you, see [haskell-resources](haskell-resources.md) for a refresher on monads. 43 | 44 | `Result` is one of many tools defined under `Reporting` which are used to manage errors. A `Report` represents some kind of error that gets printed when your program fails to compile. 45 | 46 | A `Region` describes the place in the code where the error happened; other types can be bundled with `Region` using `Located a` defined [Reporting/Annotation.hs](https://github.com/elm-lang/elm-compiler/blob/master/src/Reporting/Annotation.hs). The kinds of errors are descibed in [Reporting/Error.hs](https://github.com/elm-lang/elm-compiler/blob/master/src/Reporting/Error.hs) which farms them out to submodules: Canonicalize, Docs, Pattern, Syntax, and Type. Errors can be rendered to human-readable text or to JSON (by `--format=json` but that might not actually work?). 47 | 48 | Error detection starts by examining small pieces of code (parsing characters, duplicate record fields), expands out to larger ones (name and type conflicts within and across modules), and then focuses back in on specific things (the type of main, exhaustive pattern matches, documentation). 49 | 50 | Evan's 0.18 release greatly improved Elm's error reporting, and this is really one of the outstanding aspects of the Elm compiler: the compiler is very good at providing meaningful errors. See [Syntax.hs](https://github.com/elm-lang/elm-compiler/blob/master/src/Reporting/Error/Syntax.hs) for some examples of the helpful error messages Elm provides. 51 | 52 | ### AST 53 | The Abstract Syntax Tree is the main intermediate representation of code. It is used throughout the stages of compilation. 54 | 55 | ##### Expressions 56 | 57 | A [fully general expression](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/General.hs) has four type variables describing different pieces of information. An `Expr'` is a giant union type of possible Elm expressions, such as `Literal`, `Binop`, `Cmd`, `OutgoingPort`, etc. `Expr` is this, but with a top-level annotation that contains useful information about where the expression came from, and other debugging information. There are Source, Valid and Canonical versions of expressions, which represent the expressions at different stages of the compiler lifecycle: Source expressions are created by the parser, and when the compiler is complete they have been resolved to Canonical expressions. 58 | 59 | These versions are type aliases that provide specific types for the type variables. Optimized expressions, apparently because they need less information, are a separate union type. 60 | 61 | ##### Variables 62 | 63 | [Variable.hs](https://github.com/elm-lang/elm-compiler/blob/master/src/AST/Variable.hs) shows how variables are represented in the AST, and provides some utility functions for both general and inbuilt variables. 64 | 65 | ##### Types 66 | 67 | Elm's type system is relatively simple (which is to say, not nearly as complex as Haskell's). [Type.hs](https://github.com/elm-lang/elm-compiler/blob/master/src/AST/Type.hs) provides definitions for Raw and Canonical types, where canonical means the same as it does in the case of expressions; that the type representation is fully annotated. 68 | 69 | ##### Declarations 70 | 71 | A Declaration is anything that can be at the top level within a module: a definition, a union type, a type alias, a port, an infix declaration. There is also code for patterns, variables, literals, and types. 72 | 73 | 74 | ### Parse 75 | Parsing is the first stage of compilation, and is built around the Parsec library. Parsing is organized by parsers for expressions, declarations, literals, types, etc. The `IParser a` type is a parser that attempts to parse a string into an `a` (think JSON decoders). The parser's job is to transform valid code into the AST, and to detect and provide helpful error messages for invalid code. 76 | 77 | The [parser entry point](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Parse/Parse.hs#L23-L41) validates (`Validate.hs`) the declarations for syntax errors (not including parse errors). Such errors include type annotations missing definitions, ports without annotations, duplicate report field names, and too many/too few type variables. Validation also ensures that ports do not occur outside of the main module; the `isRoot` parameter refers to the root module (i.e. Main), not the root user. 78 | 79 | ### Canonicalize 80 | Canonicalization enriches the AST with more information in preparation for type inference. It determines what is visible where, and ensures there are no scoping problems. Canonicalization also sorts declarations by dependency. 81 | 82 | ### Type Inference 83 | There's no shortage of academic papers on type inference, and what Elm has is relatively basic, but still quite complex. Type inference is a constraint-solving algorithm that works by unifying constraints to produce the most general possible type given the constraints. 84 | 85 | (I don't really know what's going on but Evan had some tidbits here: https://github.com/elm-lang/elm-compiler/issues/1281) 86 | 87 | ### Nitpick 88 | Nitpick is a collection of mostly-unrelated checks that happen after type inference. Nitpicking verifies the type of `main`, adds warnings for missing type annotations, and (I think?) flags inexhaustive pattern matches. 89 | 90 | ### Generate 91 | Code generation traverses the AST and outputs JavaScript, with help from the `Language.ECMAScript3` Haskell package. The code is triggered from [Compiler.hs](https://github.com/elm-lang/elm-compiler/blob/master/src/Elm/Compiler.hs), entering the Generate directory through the `generate` function in [JavaScript.hs](https://github.com/elm-lang/elm-compiler/blob/master/src/Generate/JavaScript.hs). Much of the generate process occurs in [elm-make](https://github.com/elm-lang/elm-make), including the generation of `.elmi` and `.elmo` files, crawling dependencies, and the provision of [boiler JS code](https://github.com/elm-lang/elm-make/blob/master/src/Pipeline/Generate.hs) necessary for the JS runtime. 92 | 93 | The generated JS is a combination of two different definition sets, the `defsList` (Elm code generated from libraries and source), and the `managerStmts` (effects managers). 94 | 95 | ##### defsList 96 | 97 | The list of definitions is generated the the [generateDef function](https://github.com/elm-lang/elm-compiler/blob/master/src/Generate/JavaScript/Expression.hs#L89). Essentially what this does is delegate to a big `case` statement that transforms the list of Elm expressions into JS expressions, in Haskell types, through the [ECMAScript 3 package](https://hackage.haskell.org/package/language-ecmascript). These expressions are then 'printed' to [stmtsToText function](https://github.com/elm-lang/elm-compiler/blob/master/src/Generate/JavaScript/Builder.hs#L152) in [Builder.hs](https://github.com/elm-lang/elm-compiler/blob/master/src/Generate/JavaScript/Builder.hs). Most of the hard work in this translation is contained in the ECMAScript definitions, which allow the Elm compiler to meaningfully represent a JS program in Haskell types. 98 | 99 | The JS code that is generated is then padded by some boilerplate JS in elm-make, which does all the work of setting up the connections between the browser and the code generated by the Elm compiler. It is elm-make that generates elm-stuff and other build artifacts associated with the actual CLI interface. 100 | 101 | ##### managerStmts 102 | 103 | To come: what exactly are effects managers? [This tutorial on effects](https://guide.elm-lang.org/effect_managers/) is incomplete, which makes it hard to tell exactly. 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /glossary.md: -------------------------------------------------------------------------------- 1 | # Type Glossary 2 | 3 | This is a procedurally generated list of all types defined by the 0.16 Elm compiler. 4 | 5 | For those unfamiliar with Haskell, 6 | * `data` is equivalent to Elm's `type` 7 | * `type` is equivalent to `type alias` 8 | * `newType` is like `type` except there's only one tag, and so it disappears at runtime. 9 | 10 | Name | Definition | Defined (link) 11 | -----|------------|--------------- 12 | ADTs | `type ADTs = Map.Map String (AdtInfo String)` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L33-L0) 13 | AdtInfo | `type AdtInfo v = ( [String], [(v, [Type.Canonical])] )` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L35-L0) 14 | Alias | `data Alias = Alias`
` { aliasComment :: Maybe String`
` , aliasArgs :: [String]`
` , aliasType :: Type.Type`
` }` | [Docs.AST](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Docs/AST.hs#L26-L30) 15 | Alias | `data Alias = Alias`
` { aliasName :: String`
` , aliasComment :: String`
` , aliasArgs :: [String]`
` , aliasType :: Type.Type`
` }` | [Elm.Docs](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Docs.hs#L31-L36) 16 | AliasError | `data AliasError`
` = ArgMismatch Var.Canonical Int Int`
` | SelfRecursive String [String] Type.Raw`
` | MutuallyRecursive [(Region.Region, String, [String], Type.Raw)]` | [Reporting.Error.Canonicalize](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Canonicalize.hs#L88-L91) 17 | Aliased | `data Aliased t`
` = Holey t`
` | Filled t`
` deriving (Eq, Ord)` | [AST.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Type.hs#L45-L48) 18 | Aliases | `type Aliases = Map.Map String ([String], Type.Canonical)` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L32-L0) 19 | AlmostCanonicalModule | `type AlmostCanonicalModule =`
` Module.Module`
` Docs.Centralized`
` ([Module.DefaultImport], [Module.UserImport])`
` [Var.Value]`
` (Module.Body Canonical.Expr)` | [Canonicalize](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Canonicalize.hs#L68-L73) 20 | Annotated | `data Annotated annotation a`
` = A annotation a` | [Reporting.Annotation](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Annotation.hs#L9-L10) 21 | AppStructure | `data AppStructure`
` = List Variable`
` | Tuple [Variable]`
` | Other` | [Type.Unify](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Unify.hs#L421-L424) 22 | Assoc | `data Assoc = L | N | R`
` deriving (Eq)` | [AST.Declaration](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Declaration.hs#L26-L27) 23 | Assoc | `type Assoc =`
` Can.Expr -> Can.Expr -> (Can.Expr, Can.Expr)` | [Optimize](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Optimize.hs#L498-L499) 24 | Body | `data Body expr = Body`
` { program :: expr`
` , types :: Types`
` , fixities :: [(Decl.Assoc, Int, String)]`
` , aliases :: Aliases`
` , datatypes :: ADTs`
` , ports :: [String]`
` }` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L75-L82) 25 | Branch | `data Branch =`
` Branch`
` { _goal :: Int`
` , _patterns :: [(Path, CPattern)]`
` }` | [Optimize.DecisionTree](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Optimize/DecisionTree.hs#L121-L125) 26 | CPattern | `type CPattern = P.CanonicalPattern` | [Optimize.DecisionTree](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Optimize/DecisionTree.hs#L27-L0) 27 | Canonical | `data Canonical = Canonical`
` { _package :: Package.Name`
` , _module :: Raw`
` }`
` deriving (Eq, Ord, Show)` | [AST.Module.Name](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module/Name.hs#L12-L16) 28 | Canonical | `data Canonical`
` = Lambda Canonical Canonical`
` | Var String`
` | Type Var.Canonical`
` | App Canonical [Canonical]`
` | Record [(String, Canonical)] (Maybe Canonical)`
` | Aliased Var.Canonical [(String, Canonical)] (Aliased Canonical)`
` deriving (Eq, Ord)` | [AST.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Type.hs#L35-L42) 29 | Canonical | `data Canonical = Canonical`
` { home :: !Home`
` , name :: !String`
` }`
` deriving (Eq, Ord)` | [AST.Variable](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Variable.hs#L41-L45) 30 | CanonicalAdt | `type CanonicalAdt = (Var.Canonical, AdtInfo Var.Canonical)` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L36-L0) 31 | CanonicalDecl | `type CanonicalDecl =`
` A.Commented (Declaration' CanonicalPort Canonical.Def Type.Canonical Canonical.Expr)` | [AST.Declaration](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Declaration.hs#L53-L54) 32 | CanonicalModule | `type CanonicalModule =`
` Module Docs.Centralized [Name.Raw] [Var.Value] (Body Canonical.Expr)` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L57-L58) 33 | CanonicalName | `type CanonicalName = ModuleName.Canonical` | [Elm.Compiler.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Compiler/Module.hs#L55-L0) 34 | CanonicalPattern | `type CanonicalPattern =`
` Pattern R.Region Var.Canonical` | [AST.Pattern](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Pattern.hs#L33-L34) 35 | CanonicalPort | `newtype CanonicalPort`
` = CanonicalPort (General.PortImpl Canonical.Expr Type.Canonical)` | [AST.Declaration](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Declaration.hs#L69-L70) 36 | Centralized | `type Centralized = Docs (Maybe Type.Type)` | [Docs.AST](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Docs/AST.hs#L19-L0) 37 | Checked | `type Checked = Docs Type.Type` | [Docs.AST](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Docs/AST.hs#L21-L0) 38 | Code | `data Code`
` = JsExpr (Expression ())`
` | JsBlock [Statement ()]` | [Generate.JavaScript.Expression](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Generate/JavaScript/Expression.hs#L24-L26) 39 | CommandError | `data CommandError`
` = MissingExe String`
` | CommandFailed String String` | [Elm.Utils](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Utils.hs#L50-L52) 40 | Commented | `type Commented a =`
` Annotated (R.Region, Maybe String) a` | [Reporting.Annotation](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Annotation.hs#L17-L18) 41 | Constraint | `data Constraint a b`
` = CTrue`
` | CSaveEnv`
` | CEqual Error.Hint R.Region a a`
` | CAnd [Constraint a b]`
` | CLet [Scheme a b] (Constraint a b)`
` | CInstance R.Region SchemeName a` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L125-L131) 42 | Content | `data Content`
` = Structure (Term1 Variable)`
` | Atom Var.Canonical`
` | Var Flex (Maybe Super) (Maybe String)`
` | Alias Var.Canonical [(String,Variable)] Variable`
` | Error` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L74-L79) 43 | Context | `type Context = Maybe (String, Int, [String])` | [Optimize](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Optimize.hs#L195-L0) 44 | Context | `data Context`
` = None`
` | Func`
` | App` | [Reporting.Render.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Render/Type.hs#L159-L162) 45 | Context | `data Context = Context`
` { _packageName :: Package.Name`
` , _isRoot :: Bool`
` , _isExposed :: Bool`
` , _dependencies :: [PublicModule.CanonicalName]`
` }` | [Elm.Compiler](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Compiler.hs#L92-L97) 46 | Context | `data Context = Context`
` { _orientation :: Orientation`
` , _first :: Variable`
` , _firstDesc :: Descriptor`
` , _second :: Variable`
` , _secondDesc :: Descriptor`
` }` | [Type.Unify](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Unify.hs#L47-L53) 47 | Context | `data Context = None | ADT | Function` | [Elm.Compiler.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Compiler/Type.hs#L33-L0) 48 | Decider | `data Decider a`
` = Leaf a`
` | Chain`
` { _testChain :: [(DT.Path, DT.Test)]`
` , _success :: Decider a`
` , _failure :: Decider a`
` }`
` | FanOut`
` { _path :: DT.Path`
` , _tests :: [(DT.Test, Decider a)]`
` , _fallback :: Decider a`
` }`
` deriving (Eq)` | [AST.Expression.Optimized](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Optimized.hs#L60-L72) 49 | DecisionTree | `data DecisionTree`
` = Match Int`
` | Decision`
` { _test :: Path`
` , _edges :: [(Test, DecisionTree)]`
` , _default :: Maybe DecisionTree`
` }`
` deriving (Eq)` | [Optimize.DecisionTree](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Optimize/DecisionTree.hs#L69-L76) 50 | Declaration' | `data Declaration' port def tipe expr`
` = Definition def`
` | Datatype String [String] [(String, [tipe])]`
` | TypeAlias String [String] tipe`
` | Port port`
` | Fixity Assoc Int String` | [AST.Declaration](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Declaration.hs#L16-L21) 51 | Def | `data Def`
` = Definition Facts Pattern.CanonicalPattern Expr (Maybe (A.Located Type.Canonical))` | [AST.Expression.Canonical](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Canonical.hs#L23-L24) 52 | Def | `data Def`
` = Def Facts String Expr`
` | TailDef Facts String [String] Expr` | [AST.Expression.Optimized](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Optimized.hs#L20-L22) 53 | Def | `data Def`
` = Definition Pattern.RawPattern Expr (Maybe Type.Raw)` | [AST.Expression.Valid](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Valid.hs#L23-L24) 54 | Def | `type Def =`
` A.Located Def'` | [AST.Expression.Source](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Source.hs#L24-L25) 55 | Def' | `data Def'`
` = Definition Pattern.RawPattern Expr`
` | TypeAnnotation String Type.Raw` | [AST.Expression.Source](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Source.hs#L28-L30) 56 | DefaultImport | `type DefaultImport = (Name.Raw, ImportMethod)` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L101-L0) 57 | Descriptor | `data Descriptor = Descriptor`
` { _content :: Content`
` , _rank :: Int`
` , _mark :: Int`
` , _copy :: Maybe Variable`
` }` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L66-L71) 58 | Dict | `type Dict a =`
` Map.Map String (Set.Set a)` | [Canonicalize.Environment](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Canonicalize/Environment.hs#L28-L29) 59 | Diff | `data Diff a`
` = Diff a a`
` | Same a` | [Reporting.Render.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Render/Type.hs#L103-L105) 60 | Docs | `data Docs t = Docs`
` { comment :: String`
` , aliases :: Map.Map String (A.Located Alias)`
` , types :: Map.Map String (A.Located Union)`
` , values :: Map.Map String (A.Located (Value t))`
` }` | [Docs.AST](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Docs/AST.hs#L11-L16) 61 | Documentation | `data Documentation = Documentation`
` { moduleName :: Module.Name`
` , comment :: String`
` , aliases :: [Alias]`
` , types :: [Union]`
` , values :: [Value]`
` , version :: Version`
` }` | [Elm.Docs](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Docs.hs#L21-L28) 62 | DoubleFields | `type DoubleFields =`
` Map.Map String (Type.Canonical,Type.Canonical)` | [Reporting.Render.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Render/Type.hs#L331-L332) 63 | Env | `data Env = Env`
` { _hasTailCall :: Bool`
` , _uid :: Int`
` , _variantDict :: DT.VariantDict`
` , _home :: ModuleName.Canonical`
` }` | [Optimize.Environment](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Optimize/Environment.hs#L25-L30) 64 | Env | `type Env = Map.Map String (A.Located Variable)` | [Type.State](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/State.hs#L34-L0) 65 | Environment | `data Environment = Env`
` { _home :: ModuleName.Canonical`
` , _values :: Dict Var.Canonical`
` , _adts :: Dict Var.Canonical`
` , _aliases :: Dict (Var.Canonical, [String], Type.Canonical)`
` , _patterns :: Dict (Var.Canonical, Int)`
` }` | [Canonicalize.Environment](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Canonicalize/Environment.hs#L19-L25) 66 | Environment | `data Environment = Environment`
` { _constructor :: Map.Map String (IO (Int, [Variable], [Type], Type))`
` , _types :: TypeDict`
` , _value :: TypeDict`
` }` | [Type.Environment](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Environment.hs#L27-L31) 67 | Error | `data Error`
` = Parse [Parsec.Message]`
` | BadFunctionName Int`
` | BadPattern String`
` | InfixDuplicate String`
` | TypeWithoutDefinition String`
` | PortWithoutAnnotation String`
` | UnexpectedPort`
` | DuplicateFieldName String`
` | DuplicateValueDeclaration String`
` | DuplicateTypeDeclaration String`
` | DuplicateDefinition String`
` | UnboundTypeVarsInUnion String [String] [String]`
` | UnboundTypeVarsInAlias String [String] [String]`
` | UnusedTypeVarsInAlias String [String] [String]`
` | MessyTypeVarsInAlias String [String] [String] [String]` | [Reporting.Error.Syntax](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Syntax.hs#L14-L29) 68 | Error | `data Error`
` = Mismatch Mismatch`
` | BadMain Type.Canonical`
` | InfiniteType String Type.Canonical` | [Reporting.Error.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Type.hs#L23-L26) 69 | Error | `data Error`
` = NoDocs`
` | OnlyInDocs String [String]`
` | OnlyInExports [String]`
` | NoComment String`
` | NoType String` | [Reporting.Error.Docs](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Docs.hs#L11-L16) 70 | Error | `data Error`
` = Var VarError`
` | Pattern PatternError`
` | Alias AliasError`
` | Import ModuleName.Raw ImportError`
` | Export String [String]`
` | DuplicateExport String`
` | Port PortError` | [Reporting.Error.Canonicalize](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Canonicalize.hs#L18-L25) 71 | Error | `data Error`
` = Syntax Syntax.Error`
` | Canonicalize Canonicalize.Error`
` | Type Type.Error`
` | Pattern Pattern.Error`
` | Docs Docs.Error` | [Reporting.Error](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error.hs#L22-L27) 72 | Error | `newtype Error =`
` Error (A.Located Error.Error)` | [Elm.Compiler](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Compiler.hs#L141-L142) 73 | Error | `data Error`
` = Incomplete Origin [Pattern.Pattern]`
` | Redundant` | [Reporting.Error.Pattern](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Pattern.hs#L13-L15) 74 | Expr | `type Expr annotation definition variable tipe =`
` A.Annotated annotation (Expr' annotation definition variable tipe)` | [AST.Expression.General](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/General.hs#L35-L36) 75 | Expr | `data Expr`
` = Literal Literal.Literal`
` | Var Var.Canonical`
` | Range Expr Expr`
` | ExplicitList [Expr]`
` | Binop Var.Canonical Expr Expr`
` | Function [String] Expr`
` | Call Expr [Expr]`
` | TailCall String [String] [Expr]`
` | If [(Expr, Expr)] Expr`
` | Let [Def] Expr`
` | Case String (Decider Choice) [(Int, Expr)]`
` | Data String [Expr]`
` | DataAccess Expr Int`
` | Access Expr String`
` | Update Expr [(String, Expr)]`
` | Record [(String, Expr)]`
` | Port (General.PortImpl Expr Type.Canonical)`
` | GLShader String String Literal.GLShaderTipe`
` | Crash ModuleName.Canonical R.Region (Maybe Expr)` | [AST.Expression.Optimized](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Optimized.hs#L38-L57) 76 | Expr | `type Expr =`
` General.Expr R.Region Def Var.Raw Type.Raw` | [AST.Expression.Source](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Source.hs#L16-L17) 77 | Expr | `type Expr =`
` General.Expr R.Region Def Var.Canonical Type.Canonical` | [AST.Expression.Canonical](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Canonical.hs#L15-L16) 78 | Expr | `type Expr =`
` General.Expr R.Region Def Var.Raw Type.Raw` | [AST.Expression.Valid](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Valid.hs#L15-L16) 79 | Expr' | `type Expr' =`
` General.Expr' R.Region Def Var.Canonical Type.Canonical` | [AST.Expression.Canonical](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Canonical.hs#L19-L20) 80 | Expr' | `type Expr' =`
` General.Expr' R.Region Def Var.Raw Type.Raw` | [AST.Expression.Source](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Source.hs#L20-L21) 81 | Expr' | `type Expr' =`
` General.Expr' R.Region Def Var.Raw Type.Raw` | [AST.Expression.Valid](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Valid.hs#L19-L20) 82 | Expr' | `data Expr' ann def var typ`
` = Literal Literal.Literal`
` | Var var`
` | Range (Expr ann def var typ) (Expr ann def var typ)`
` | ExplicitList [Expr ann def var typ]`
` | Binop var (Expr ann def var typ) (Expr ann def var typ)`
` | Lambda (Pattern.Pattern ann var) (Expr ann def var typ)`
` | App (Expr ann def var typ) (Expr ann def var typ)`
` | If [(Expr ann def var typ, Expr ann def var typ)] (Expr ann def var typ)`
` | Let [def] (Expr ann def var typ)`
` | Case (Expr ann def var typ) [(Pattern.Pattern ann var, Expr ann def var typ)]`
` | Data String [Expr ann def var typ]`
` | Access (Expr ann def var typ) String`
` | Update (Expr ann def var typ) [(String, Expr ann def var typ)]`
` | Record [(String, Expr ann def var typ)]`
` -- for type checking and code gen only`
` | Port (PortImpl (Expr ann def var typ) typ)`
` | GLShader String String Literal.GLShaderTipe` | [AST.Expression.General](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/General.hs#L39-L56) 83 | ExtensionStructure | `data ExtensionStructure`
` = Empty`
` | Extension` | [Type.Unify](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Unify.hs#L647-L649) 84 | Facts | `data Facts = Facts`
` { dependencies :: [Var.TopLevel]`
` }` | [AST.Expression.Canonical](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Canonical.hs#L27-L29) 85 | Facts | `data Facts = Facts`
` { home :: Maybe ModuleName.Canonical`
` , dependencies :: [Var.TopLevel]`
` }` | [AST.Expression.Optimized](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/Optimized.hs#L25-L28) 86 | Fields | `type Fields =`
` Map.Map String Type.Canonical` | [Reporting.Render.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Render/Type.hs#L327-L328) 87 | Flex | `data Flex`
` = Rigid`
` | Flex` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L82-L84) 88 | Fragment | `data Fragment = Fragment`
` { typeEnv :: Map.Map String (A.Located Type)`
` , vars :: [Variable]`
` , typeConstraint :: TypeConstraint`
` }` | [Type.Fragment](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Fragment.hs#L11-L15) 89 | GLTipe | `data GLTipe`
` = Int`
` | Float`
` | V2`
` | V3`
` | V4`
` | M4`
` | Texture`
` deriving (Eq)` | [AST.Literal](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Literal.hs#L26-L34) 90 | Header | `data Header imports = Header`
` { _name :: Name.Raw`
` , _docs :: A.Located (Maybe String)`
` , _exports :: Var.Listing (A.Located Var.Value)`
` , _imports :: imports`
` }` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L88-L93) 91 | Hint | `data Hint`
` = CaseBranch Int Region.Region`
` | Case`
` | IfCondition`
` | IfBranches`
` | MultiIfBranch Int Region.Region`
` | If`
` | List`
` | ListElement Int Region.Region`
` | BinopLeft Var.Canonical Region.Region`
` | BinopRight Var.Canonical Region.Region`
` | Binop Var.Canonical`
` | Function (Maybe Var.Canonical)`
` | UnexpectedArg (Maybe Var.Canonical) Int Int Region.Region`
` | FunctionArity (Maybe Var.Canonical) Int Int Region.Region`
` | BadTypeAnnotation String`
` | Instance String`
` | Literal String`
` | Pattern Pattern`
` | Shader`
` | Range`
` | Lambda`
` | Record` | [Reporting.Error.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Type.hs#L52-L74) 92 | Home | `data Home`
` = BuiltIn`
` | Module ModuleName.Canonical`
` | TopLevel ModuleName.Canonical`
` | Local`
` deriving (Eq, Ord)` | [AST.Variable](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Variable.hs#L33-L38) 93 | IParser | `type IParser a = ParsecT String OpTable SourceM a` | [Parse.Helpers](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Parse/Helpers.hs#L48-L0) 94 | ImportError | `data ImportError`
` = ModuleNotFound [ModuleName.Raw]`
` | ValueNotFound String [String]` | [Reporting.Error.Canonicalize](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Canonicalize.hs#L69-L71) 95 | ImportMethod | `data ImportMethod = ImportMethod`
` { alias :: Maybe String`
` , exposedVars :: !(Var.Listing Var.Value)`
` }` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L104-L107) 96 | Info | `data Info = Info`
` { iSchemes :: [TypeScheme]`
` , iRigid :: [Variable]`
` , iFlex :: [Variable]`
` , iHeaders :: Map.Map String (A.Located Type)`
` , iC2 :: TypeConstraint`
` , iC1 :: TypeConstraint`
` }` | [Type.Constrain.Expression](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Constrain/Expression.hs#L481-L488) 97 | Interface | `data Interface = Interface`
` { iVersion :: Package.Version`
` , iPackage :: Package.Name`
` , iExports :: [Var.Value]`
` , iTypes :: Types`
` , iImports :: [Name.Raw]`
` , iAdts :: ADTs`
` , iAliases :: Aliases`
` , iFixities :: [(Decl.Assoc, Int, String)]`
` , iPorts :: [String]`
` }` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L113-L123) 98 | Interface | `type Interface = Module.Interface` | [Elm.Compiler.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Compiler/Module.hs#L33-L0) 99 | Interfaces | `type Interfaces = Map.Map Name.Canonical Interface` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L29-L0) 100 | Interfaces | `type Interfaces = Module.Interfaces` | [Elm.Compiler.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Compiler/Module.hs#L36-L0) 101 | JSType | `data JSType`
` = JSNumber`
` | JSInt`
` | JSBoolean`
` | JSString`
` | JSArray`
` | JSObject [String]` | [Generate.JavaScript.Port](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Generate/JavaScript/Port.hs#L28-L34) 102 | Listing | `data Listing a = Listing`
` { _explicits :: [a]`
` , _open :: Bool`
` }`
` deriving (Eq, Ord)` | [AST.Variable](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Variable.hs#L202-L206) 103 | Literal | `data Literal`
` = IntNum Int`
` | FloatNum Double`
` | Chr Char`
` | Str String`
` | Boolean Bool`
` deriving (Eq, Ord)` | [AST.Literal](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Literal.hs#L7-L13) 104 | Localizer | `newtype Localizer =`
` Localizer RenderType.Localizer` | [Elm.Compiler](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Compiler.hs#L130-L131) 105 | Localizer | `type Localizer =`
` Map.Map String String` | [Reporting.Render.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Render/Type.hs#L83-L84) 106 | Located | `type Located a =`
` Annotated R.Region a` | [Reporting.Annotation](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Annotation.hs#L13-L14) 107 | Mismatch | `data Mismatch`
` = Mismatch Variable Variable (Maybe Error.Reason)` | [Type.Unify](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Unify.hs#L74-L75) 108 | Mismatch | `data Mismatch = MismatchInfo`
` { _hint :: Hint`
` , _leftType :: Type.Canonical`
` , _rightType :: Type.Canonical`
` , _reason :: Maybe Reason`
` }` | [Reporting.Error.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Type.hs#L29-L34) 109 | Module | `data Module docs imports exports body = Module`
` { name :: Name.Canonical`
` , path :: FilePath`
` , docs :: A.Located (Maybe docs)`
` , exports :: exports`
` , imports :: imports`
` , body :: body`
` }` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L65-L72) 110 | Name | `newtype Name = Name ModuleName.Raw`
` deriving (Eq, Ord)` | [Elm.Compiler.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Compiler/Module.hs#L51-L52) 111 | Name | `data Name = Name`
` { user :: String`
` , project :: String`
` }`
` deriving (Eq, Ord, Show)` | [Elm.Package](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Package.hs#L14-L18) 112 | NameState | `data NameState = NameState`
` { _freeNames :: [String]`
` , _numberPrimes :: Int`
` , _comparablePrimes :: Int`
` , _appendablePrimes :: Int`
` , _compAppendPrimes :: Int`
` }` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L348-L354) 113 | Node | `type Node = ((R.Region, String, [String], Type.Raw), String, [String])` | [Canonicalize.Setup](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Canonicalize/Setup.hs#L216-L0) 114 | OpTable | `type OpTable = Map.Map String (Int, Decl.Assoc)` | [Parse.Helpers](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Parse/Helpers.hs#L46-L0) 115 | Optimized | `type Optimized =`
` Module Docs.Centralized [Name.Raw] [Var.Value] (Body [Optimized.Def])` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L61-L62) 116 | Optimizer | `type Optimizer a =`
` State.State Env a` | [Optimize.Environment](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Optimize/Environment.hs#L16-L17) 117 | Orientation | `data Orientation = ExpectedActual | ActualExpected` | [Type.Unify](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Unify.hs#L56-L0) 118 | Origin | `data Origin`
` = Arg`
` | LetBound`
` | Case` | [Reporting.Error.Pattern](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Pattern.hs#L18-L21) 119 | Package | `type Package = (Name, Version)` | [Elm.Package](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Package.hs#L21-L0) 120 | Pair | `data Pair = Pair`
` { _index :: Int`
` , _var1 :: Variable`
` , _var2 :: Variable`
` , _region :: R.Region`
` }` | [Type.Constrain.Expression](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Constrain/Expression.hs#L405-L410) 121 | ParseHint | `data ParseHint = ParseHint`
` { _messages :: [String]`
` , _expected :: Set.Set String`
` }`
` deriving (Show)` | [Reporting.Error.Syntax](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Syntax.hs#L308-L312) 122 | Patch | `data Patch`
` = Value String Var.Canonical`
` | Union String Var.Canonical`
` | Alias String (Var.Canonical, [String], Type.Canonical)`
` | Pattern String (Var.Canonical, Int)` | [Canonicalize.Environment](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Canonicalize/Environment.hs#L49-L53) 123 | Path | `data Path`
` = Position Int Path`
` | Field String Path`
` | Empty`
` | Alias`
` deriving (Eq)` | [Optimize.DecisionTree](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Optimize/DecisionTree.hs#L85-L90) 124 | Pattern | `data Pattern`
` = Data Var.Canonical [Pattern]`
` | Record [String]`
` | Alias String Pattern`
` | Var String`
` | Anything`
` | Literal L.Literal`
` | AnythingBut (Set.Set L.Literal)`
` deriving (Eq)` | [Nitpick.Pattern](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Nitpick/Pattern.hs#L12-L20) 125 | Pattern | `type Pattern ann var =`
` A.Annotated ann (Pattern' ann var)` | [AST.Pattern](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Pattern.hs#L12-L13) 126 | Pattern | `data Pattern`
` = PVar String`
` | PAlias String`
` | PData String`
` | PRecord` | [Reporting.Error.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Type.hs#L77-L81) 127 | Pattern' | `data Pattern' ann var`
` = Data var [Pattern ann var]`
` | Record [String]`
` | Alias String (Pattern ann var)`
` | Var String`
` | Anything`
` | Literal L.Literal` | [AST.Pattern](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Pattern.hs#L16-L22) 128 | PatternError | `data PatternError`
` = PatternArgMismatch Var.Canonical Int Int` | [Reporting.Error.Canonicalize](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Canonicalize.hs#L56-L57) 129 | Pool | `data Pool = Pool`
` { maxRank :: Int`
` , inhabitants :: [Variable]`
` }` | [Type.State](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/State.hs#L20-L23) 130 | Port | `data Port t`
` = Normal t`
` | Signal { root :: t, arg :: t }`
` deriving (Eq)` | [AST.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Type.hs#L51-L54) 131 | PortError | `data PortError = PortError`
` { portName :: String`
` , portIsInbound :: Bool`
` , portRootType :: Type.Canonical`
` , portLocalType :: Type.Canonical`
` , portMessage :: Maybe String`
` }` | [Reporting.Error.Canonicalize](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Canonicalize.hs#L103-L109) 132 | PortImpl | `data PortImpl expr tipe`
` = In String (Type.Port tipe)`
` | Out String expr (Type.Port tipe)`
` | Task String expr (Type.Port tipe)`
` deriving (Eq)` | [AST.Expression.General](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Expression/General.hs#L61-L65) 133 | Position | `data Position = Position`
` { line :: Int`
` , column :: Int`
` }`
` deriving (Eq, Show)` | [Reporting.Region](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Region.hs#L16-L20) 134 | Raw | `data Raw = Raw`
` { rawAliases :: Map.Map String (A.Located Docs.Alias)`
` , rawTypes :: Map.Map String (A.Located Docs.Union)`
` , rawValues :: Map.Map String (A.Located (Maybe String, Maybe Type.Type))`
` , rawFixities :: Map.Map String (String, Int)`
` }` | [Docs.Centralize](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Docs/Centralize.hs#L41-L46) 135 | Raw | `newtype Raw = Raw String`
` deriving (Eq, Ord)` | [AST.Variable](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Variable.hs#L14-L15) 136 | Raw | `type Raw =`
` A.Located Raw'` | [AST.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Type.hs#L23-L24) 137 | Raw | `type Raw = [String] -- must be non-empty` | [AST.Module.Name](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module/Name.hs#L9-L0) 138 | Raw' | `data Raw'`
` = RLambda Raw Raw`
` | RVar String`
` | RType Var.Raw`
` | RApp Raw [Raw]`
` | RRecord [(String, Raw)] (Maybe Raw)` | [AST.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Type.hs#L27-L32) 139 | RawPattern | `type RawPattern =`
` Pattern R.Region Var.Raw` | [AST.Pattern](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Pattern.hs#L25-L26) 140 | RawPattern' | `type RawPattern' =`
` Pattern' R.Region Var.Raw` | [AST.Pattern](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Pattern.hs#L29-L30) 141 | RawResult | `data RawResult e a`
` = Ok a`
` | Err e` | [Reporting.Result](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Result.hs#L20-L22) 142 | RawResult | `data RawResult err a`
` = Ok a`
` | Err [err]` | [Canonicalize.Result](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Canonicalize/Result.hs#L22-L24) 143 | Reason | `data Reason`
` = MessyFields [String] [String]`
` | IntFloat`
` | TooLongComparableTuple Int`
` | BadVar (Maybe VarType) (Maybe VarType)` | [Reporting.Error.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Type.hs#L37-L41) 144 | RecordStructure | `data RecordStructure = RecordStructure`
` { _fields :: Map.Map String Variable`
` , _extVar :: Variable`
` , _extStruct :: ExtensionStructure`
` }` | [Type.Unify](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Unify.hs#L640-L644) 145 | Region | `data Region = Region`
` { start :: Position`
` , end :: Position`
` }`
` deriving (Eq, Show)` | [Reporting.Region](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Region.hs#L9-L13) 146 | Report | `data Report = Report`
` { _title :: String`
` , _highlight :: Maybe R.Region`
` , _preHint :: Doc`
` , _postHint :: Doc`
` }` | [Reporting.Report](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Report.hs#L28-L33) 147 | Result | `data Result warning error result =`
` Result`
` (Maybe RenderType.Localizer, [A.Located warning])`
` (RawResult [A.Located error] result)` | [Reporting.Result](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Result.hs#L14-L17) 148 | Result | `data Result err a =`
` Result (Set.Set ModuleName.Raw) (RawResult err a)` | [Canonicalize.Result](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Canonicalize/Result.hs#L18-L19) 149 | Result | `data Result = Result`
` { _docs :: Maybe Docs.Documentation`
` , _interface :: PublicModule.Interface`
` , _js :: String`
` }` | [Elm.Compiler](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Compiler.hs#L100-L104) 150 | Result | `type Result w a = R.Result w Error.Error a` | [Docs.Check](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Docs/Check.hs#L25-L0) 151 | ResultErr | `type ResultErr a = Result (A.Located Error.Error) a` | [Canonicalize.Result](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Canonicalize/Result.hs#L15-L0) 152 | Scheme | `data Scheme a b = Scheme`
` { _rigidQuantifiers :: [b]`
` , _flexibleQuantifiers :: [b]`
` , _constraint :: Constraint a b`
` , _header :: Map.Map String (A.Located a)`
` }` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L137-L142) 153 | SchemeName | `type SchemeName = String` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L134-L0) 154 | Solver | `type Solver = State.StateT SolverState IO` | [Type.State](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/State.hs#L37-L0) 155 | SolverState | `data SolverState = SS`
` { sEnv :: Env`
` , sSavedEnv :: Env`
` , sPool :: Pool`
` , sMark :: Int`
` , sError :: [A.Located Error.Error]`
` }` | [Type.State](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/State.hs#L41-L47) 156 | SourceDecl | `data SourceDecl`
` = Comment String`
` | Decl (A.Located SourceDecl')` | [AST.Declaration](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Declaration.hs#L44-L46) 157 | SourceDecl' | `type SourceDecl' =`
` Declaration' SourcePort Source.Def Type.Raw Source.Expr` | [AST.Declaration](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Declaration.hs#L40-L41) 158 | SourceM | `type SourceM = State SourcePos` | [Parse.Helpers](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Parse/Helpers.hs#L47-L0) 159 | SourceModule | `type SourceModule =`
` Module`
` String`
` [UserImport]`
` (Var.Listing (A.Located Var.Value))`
` [Decl.SourceDecl]` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L41-L46) 160 | SourcePort | `data SourcePort`
` = PortAnnotation String Type.Raw`
` | PortDefinition String Source.Expr` | [AST.Declaration](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Declaration.hs#L59-L61) 161 | Style | `data Style`
` = Elide`
` | Full` | [Reporting.Render.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Render/Type.hs#L463-L465) 162 | Subs | `data Subs = Subs`
` { _substitutions :: Map.Map String Opt.Expr`
` , _definitions :: [(String, Opt.Expr)]`
` }` | [Optimize.Inline](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Optimize/Inline.hs#L36-L39) 163 | Super | `data Super`
` = Number`
` | Comparable`
` | Appendable`
` | CompAppend`
` deriving (Eq)` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L87-L92) 164 | Tag | `type Tag = String` | [Nitpick.PatternMatches](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Nitpick/PatternMatches.hs#L46-L0) 165 | TagDict | `type TagDict =`
` Map.Map Var.Home (Map.Map Tag [TagInfo])` | [Nitpick.PatternMatches](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Nitpick/PatternMatches.hs#L42-L43) 166 | TagInfo | `data TagInfo = TagInfo`
` { _tag :: Tag`
` , _arity :: Int`
` }` | [Nitpick.PatternMatches](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Nitpick/PatternMatches.hs#L49-L52) 167 | Term | `data Term1 a`
` = App1 a a`
` | Fun1 a a`
` | EmptyRecord1`
` | Record1 (Map.Map String a) a` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L43-L47) 168 | TermN | `data TermN a`
` = PlaceHolder String`
` | AliasN Var.Canonical [(String, TermN a)] (TermN a)`
` | VarN a`
` | TermN (Term1 (TermN a))` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L50-L54) 169 | Test | `data Test`
` = Constructor Var.Canonical`
` | Literal L.Literal`
` deriving (Eq, Ord)` | [Optimize.DecisionTree](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Optimize/DecisionTree.hs#L79-L82) 170 | TopLevel | `data TopLevel = TopLevelVar`
` { topHome :: ModuleName.Canonical`
` , topName :: String`
` }`
` deriving (Eq, Ord)` | [AST.Variable](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Variable.hs#L22-L26) 171 | Type | `type Type =`
` TermN Variable` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L23-L24) 172 | Type | `data Type`
` = Lambda Type Type`
` | Var String`
` | Type String`
` | App Type [Type]`
` | Record [(String, Type)] (Maybe Type)` | [Elm.Compiler.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Compiler/Type.hs#L23-L28) 173 | TypeConstraint | `type TypeConstraint =`
` Constraint Type Variable` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L31-L32) 174 | TypeDict | `type TypeDict = Map.Map String Type` | [Type.Environment](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Environment.hs#L23-L0) 175 | TypeScheme | `type TypeScheme =`
` Scheme Type Variable` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L35-L36) 176 | Types | `type Types = Map.Map String Type.Canonical` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L31-L0) 177 | Unify | `type Unify =`
` ExceptT Mismatch TS.Solver` | [Type.Unify](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Unify.hs#L43-L44) 178 | Union | `data Union = Union`
` { unionComment :: Maybe String`
` , unionArgs :: [String]`
` , unionCases :: [(String, [Type.Type])]`
` }` | [Docs.AST](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Docs/AST.hs#L33-L37) 179 | Union | `data Union = Union`
` { unionName :: String`
` , unionComment :: String`
` , unionArgs :: [String]`
` , unionCases :: [(String, [Type.Type])]`
` }` | [Elm.Docs](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Docs.hs#L39-L44) 180 | UserImport | `type UserImport = A.Located (Name.Raw, ImportMethod)` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L98-L0) 181 | ValidDecl | `type ValidDecl =`
` A.Commented (Declaration' ValidPort Valid.Def Type.Raw Valid.Expr)` | [AST.Declaration](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Declaration.hs#L49-L50) 182 | ValidModule | `type ValidModule =`
` Module`
` String`
` ([DefaultImport], [UserImport])`
` (Var.Listing (A.Located Var.Value))`
` [Decl.ValidDecl]` | [AST.Module](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Module.hs#L49-L54) 183 | ValidPort | `data ValidPort`
` = In String Type.Raw`
` | Out String Valid.Expr Type.Raw` | [AST.Declaration](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Declaration.hs#L64-L66) 184 | Value | `data Value = Value`
` { valueName :: String`
` , valueComment :: String`
` , valueType :: Type.Type`
` , valueFix :: Maybe (String,Int)`
` }` | [Elm.Docs](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Docs.hs#L47-L52) 185 | Value | `data Value`
` = Value !String`
` | Alias !String`
` | Union !String !(Listing String)`
` deriving (Eq, Ord)` | [AST.Variable](https://github.com/elm-lang/elm-compiler/blob/0.16/src/AST/Variable.hs#L225-L229) 186 | VarDict | `type VarDict = Map.Map String Variable` | [Type.Environment](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Environment.hs#L24-L0) 187 | VarError | `data VarError = VarError`
` { varKind :: String`
` , varName :: String`
` , varProblem :: VarProblem`
` , varSuggestions :: [String]`
` }` | [Reporting.Error.Canonicalize](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Canonicalize.hs#L32-L37) 188 | VarName | `type VarName =`
` Either String (ModuleName.Raw, String)` | [Canonicalize.Variable](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Canonicalize/Variable.hs#L169-L170) 189 | VarProblem | `data VarProblem`
` = Ambiguous`
` | UnknownQualifier String String`
` | QualifiedUnknown String String`
` | ExposedUnknown` | [Reporting.Error.Canonicalize](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Canonicalize.hs#L40-L44) 190 | VarType | `data VarType`
` = Number`
` | Comparable`
` | Appendable`
` | CompAppend`
` | Rigid (Maybe String)` | [Reporting.Error.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Error/Type.hs#L44-L49) 191 | Variable | `type Variable =`
` UF.Point Descriptor` | [Type.Type](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Type/Type.hs#L27-L28) 192 | VariantDict | `type VariantDict =`
` Map.Map Var.Home (Map.Map String Int)` | [Optimize.DecisionTree](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Optimize/DecisionTree.hs#L63-L64) 193 | Version | `data Version = NonCanonicalTypes | Version String` | [Elm.Docs](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Docs.hs#L55-L0) 194 | Version | `data Version = Version`
` { _major :: Int`
` , _minor :: Int`
` , _patch :: Int`
` }`
` deriving (Eq, Ord)` | [Elm.Package](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Package.hs#L143-L148) 195 | Warning | `newtype Warning =`
` Warning (A.Located Warning.Warning)` | [Elm.Compiler](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Elm/Compiler.hs#L162-L163) 196 | Warning | `data Warning`
` = UnusedImport ModuleName.Raw`
` | MissingTypeAnnotation String Type.Canonical` | [Reporting.Warning](https://github.com/elm-lang/elm-compiler/blob/0.16/src/Reporting/Warning.hs#L21-L23) 197 | -------------------------------------------------------------------------------- /haskell-resources.md: -------------------------------------------------------------------------------- 1 | # Haskell Resources 2 | 3 | For those new to Haskell, the Elm compiler codebase can be daunting. Haskell is particularly well-suited for writing compilers. Given that a compiler typically requires the generation of one large data structure, or AST, from source code, Haskell's type system comes in handy as a way to reliably handle errors and various cases of difference in the source language. 4 | 5 | - [Learn You a Haskell for Great Good](http://learnyouahaskell.com/) provides a basic introduction to Haskell, demonstrating simple use cases and pointing at the nuances of the language. It's a great place to get started if you're new to Haskell. 6 | - [Real World Haskell](http://book.realworldhaskell.org/read/) is a tutorial showing how to work with real data in Haskell, demonstrating how it can actually be used to write useful programs. This is a great follow-up to *Learn You a Haskell for Great Good*, and introduces many of the techniques used in the Elm compiler. 7 | - [All About Monads](https://wiki.haskell.org/All_About_Monads) is a handy piece of documentation that goes into depth about monads. Monads are a very important construction in the Elm compiler, as they are essentially what allows the compiler to build up state over the course of its execution, and also how it deals with files, and all the other useful 'side effects' the compiler performs. -------------------------------------------------------------------------------- /scripts/types.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This script parses the types declared in the Elm compiler into a Markdown 4 | # table. It expects the path to elm-compiler as a command-line argument and 5 | # writes to stdout. 6 | 7 | def usage 8 | puts "usage: pass elm-compiler path on command line" 9 | exit 1 10 | end 11 | 12 | return usage if ARGV[0].nil? 13 | /Version: (.*)/.match IO.read(File.join(ARGV[0], "elm-compiler.cabal")) 14 | VERSION = $1 15 | return usage if VERSION.nil? 16 | SRC = File.join(ARGV[0], "src") 17 | return usage unless File.directory?(SRC) 18 | 19 | 20 | entries = [] 21 | Entry = Struct.new("Entry", :name, :module, :line_start, :line_end, :definition) do 22 | def render 23 | ["#{self[:name]}", definition, module_name].join(" | ") 24 | end 25 | 26 | def definition 27 | self[:definition].map{|line| "`#{line}`"}.join("
") 28 | end 29 | 30 | def module_name 31 | mod = self[:module] 32 | l1 = self[:line_start] 33 | l2 = self[:line_end] 34 | "[#{mod}](https://github.com/elm-lang/elm-compiler/blob/#{VERSION}/src/#{mod.gsub(".", "/")}.hs#L#{l1}-L#{l2})" 35 | end 36 | end 37 | 38 | Dir.chdir SRC do 39 | Dir.glob(File.join("**", "*.hs")).each do |filename| 40 | current_module = "" 41 | current_entry = nil 42 | IO.readlines(filename).each_with_index do |line, i| 43 | case line 44 | when /^module ([A-Za-z.]*)/ 45 | current_module = $1 46 | when /^((new)?type|data) ([A-Za-z']*)/ 47 | entries << current_entry unless current_entry.nil? 48 | current_entry = Entry.new($3, current_module, i+1, 0, [line.rstrip]) 49 | when /^\s*$/ 50 | unless current_entry.nil? 51 | entries << current_entry 52 | current_entry = nil 53 | end 54 | else 55 | unless current_entry.nil? 56 | current_entry[:definition] << line.rstrip 57 | current_entry[:line_end] = i+1 58 | end 59 | end 60 | end 61 | end 62 | end 63 | 64 | # Remove this line to get a by-module listing 65 | entries = entries.sort_by{|entry| entry[:name]} 66 | 67 | puts <