### Clone Elm Todomvc Example Source: https://github.com/elm/compiler/blob/master/hints/init.md Use this command to start a more elaborate Elm project by cloning the Elm Todomvc example repository. ```bash git clone https://github.com/evancz/elm-todomvc.git ``` -------------------------------- ### Clone Elm SPA Example Source: https://github.com/elm/compiler/blob/master/hints/init.md Use this command to start a more elaborate Elm project by cloning the Elm SPA example repository. ```bash git clone https://github.com/rtfeldman/elm-spa-example.git ``` -------------------------------- ### Download and Install Elm Binary Source: https://github.com/elm/compiler/blob/master/installers/linux/README.md Follow these commands to download, decompress, make executable, and install the Elm binary to your system's PATH. This allows you to run Elm commands from any directory. ```bash # Move to your Desktop so you can see what is going on easier. # cd ~/ # Download the 0.19.1 binary for Linux. # # +-----------+----------------------+ # | FLAG | MEANING | # +-----------+----------------------+ # | -L | follow redirects | # | -o elm.gz | name the file elm.gz | # +-----------+----------------------+ # curl -L -o elm.gz https://github.com/elm/compiler/releases/download/0.19.1/binary-for-linux-64-bit.gz # There should now be a file named `elm.gz` on your Desktop. # # The downloaded file is compressed to make it faster to download. # This next command decompresses it, replacing `elm.gz` with `elm`. # gunzip elm.gz # There should now be a file named `elm` on your Desktop! # # Every file has "permissions" about whether it can be read, written, or executed. # So before we use this file, we need to mark this file as executable: # chmod +x elm # The `elm` file is now executable. That means running `~/Desktop/elm --help` # should work. Saying `./elm --help` works the same. # # But we want to be able to say `elm --help` without specifying the full file # path every time. We can do this by moving the `elm` binary to one of the # directories listed in your `PATH` environment variable: # sudo mv elm /usr/local/bin/ # Now it should be possible to run the `elm` binary just by saying its name! # elm --help ``` -------------------------------- ### Build Elm Windows Installer with NSIS Source: https://github.com/elm/compiler/blob/master/installers/win/README.md Use the provided batch script with NSIS installed to build the Elm installer for a specific version. ```bash make_installer.cmd 0.19.0 ``` -------------------------------- ### Manual Installation of Elm Compiler Source: https://github.com/elm/compiler/blob/master/installers/mac/README.md Follow these commands to manually install the Elm compiler by downloading, decompressing, and placing the binary in your system's PATH. ```bash # Move to your Desktop so you can see what is going on easier. # cd ~/ # Download the 0.19.1 binary for Linux. # # +-----------+----------------------+ # | FLAG | MEANING | # +-----------+----------------------+ # | -L | follow redirects | # | -o elm.gz | name the file elm.gz | # +-----------+----------------------+ # curl -L -o elm.gz https://github.com/elm/compiler/releases/download/0.19.1/binary-for-mac-64-bit.gz # There should now be a file named `elm.gz` on your Desktop. # # The downloaded file is compressed to make it faster to download. # This next command decompresses it, replacing `elm.gz` with `elm`. # gunzip elm.gz # There should now be a file named `elm` on your Desktop! # # Every file has "permissions" about whether it can be read, written, or executed. # So before we use this file, we need to mark this file as executable: # chmod +x elm # The `elm` file is now executable. That means running `~/Desktop/elm --help` # should work. Saying `./elm --help` works the same. # # But we want to be able to say `elm --help` without specifying the full file # path every time. We can do this by moving the `elm` binary to one of the # directories listed in your `PATH` environment variable: # sudo mv elm /usr/local/bin/ # Now it should be possible to run the `elm` binary just by saying its name! # elm --help ``` -------------------------------- ### Download and Install Elm Binaries on Linux Source: https://github.com/elm/compiler/blob/master/installers/npm/troubleshooting.md Use these commands to download, unzip, make executable, and move the Elm binary to a directory in your PATH. This method bypasses npm for installation. ```bash cd ~/Desktop/ curl -L -o elm.gz https://github.com/elm/compiler/releases/download/0.19.1/binary-for-linux-64-bit.gz gunzip elm.gz # unzip the file chmod +x elm # make the file executable sudo mv elm /usr/local/bin/ # put the executable in a directory likely to be listed in your PATH variable ``` -------------------------------- ### Verify Elm Version Source: https://github.com/elm/compiler/blob/master/installers/npm/README.md After installation, run this command within your project to verify the installed Elm version. This confirms that the correct binary is accessible. ```bash ./node_modules/bin/elm --version ``` -------------------------------- ### Elm Import Syntax Examples Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/earlier.md Demonstrates the new import syntax introduced in Elm 0.15, allowing for more concise and flexible module imports. ```elm import List -- Just bring `List` into scope, allowing you to say `List.map`, -- `List.filter`, etc. import List exposing (map, filter) -- Bring `List` into scope, but also bring in `map` and `filter` -- without any prefix. import List exposing ( ..) -- Bring `List` into scope, and bring in all the values in the -- module without a prefix. import List as L -- Bring `L` into scope, but not `List`. This lets you say `L.map`, -- `L.filter`, etc. import List as L exposing (map, filter) -- Bring `L` into scope along with unqualified versions of `map` -- and `filter`. import List as L exposing ( ..) -- Bring in all the values unqualified and qualified with `L`. ``` -------------------------------- ### Install Elm Package Dependency Source: https://context7.com/elm/compiler/llms.txt Use `elm install` to add a package from package.elm-lang.org to your project. The `elm.json` file is updated automatically. Ensure you use tested dependency ranges. ```bash elm install elm/http # Install elm/json for JSON decoding/encoding elm install elm/json ``` -------------------------------- ### Reasonable Shadowing Example in Elm Source: https://github.com/elm/compiler/blob/master/hints/shadowing.md This example shows a case where variable shadowing might seem reasonable, with a Maybe String and a String of the same name. However, Elm linters typically warn against this. ```elm viewName : Maybe String -> Html msg viewName name = case name of Nothing -> ... Just name -> ... ``` -------------------------------- ### Start the Elm development server with `elm reactor` Source: https://context7.com/elm/compiler/llms.txt Launches a local server at `http://localhost:8000` that compiles Elm files on demand in the browser. This eliminates the need for a build step during development. ```bash elm reactor # Output: # Go to http://localhost:8000 to see your project dashboard. ``` -------------------------------- ### Elm 0.15.1 Field Parameters Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.16.md Example of field parameters in Elm 0.15.1. ```elm type alias Foo = { prefix : String -> String } foo : Foo foo = { prefix x = "prefix" ++ x } ``` -------------------------------- ### Import and Use Modules in REPL Source: https://github.com/elm/compiler/blob/master/hints/repl.md When running `elm repl` in a project, you can import any available module. This example shows importing and using a function from `elm/html`. ```elm > import Html exposing (Html) > Html.text "hello" : Html msg ``` ```elm > Html.text : String -> Html msg ``` -------------------------------- ### Elm 0.15.1 Multi-way If Syntax Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.16.md Example of the multi-way if syntax in Elm 0.15.1. ```elm if | x < 0 -> "left" | x > 0 -> "right" | otherwise -> "neither" ``` -------------------------------- ### Install Specific Earlier Elm Versions Source: https://github.com/elm/compiler/blob/master/installers/npm/README.md To install specific earlier versions of Elm, use the corresponding version tags with npm. This allows for precise version control within projects. ```bash npm install elm@latest-0.19.0 ``` ```bash npm install elm@latest-0.18.0 ``` -------------------------------- ### Compile Elm Project Source: https://github.com/elm/compiler/blob/master/installers/npm/README.md Use this command to compile your Elm project after installation. It ensures that the correct Elm binary from your project's node_modules is used. ```bash ./node_modules/bin/elm make src/Main.elm ``` -------------------------------- ### Elm 0.16 Field Parameters Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.16.md Example of field parameters in Elm 0.16, using lambda syntax for the function. ```elm type alias Foo = { prefix : String -> String } foo : Foo foo = { prefix = \x-> "prefix" ++ x } ``` -------------------------------- ### Install Latest Elm 0.19.1 via npm Source: https://github.com/elm/compiler/blob/master/installers/npm/README.md Use this command to download the latest Elm 0.19.1 binary. This is useful for projects requiring a specific Elm version managed by npm. ```bash npm install elm@latest-0.19.1 ``` -------------------------------- ### Elm 0.16 If-Then-Else Syntax Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.16.md Example of the equivalent if-then-else construct in Elm 0.16, replacing multi-way if. ```elm if x < 0 then "left" else if x > 0 then "right" else "neither" ``` -------------------------------- ### Configure HTTPS_PROXY for npm Installs Source: https://github.com/elm/compiler/blob/master/installers/npm/troubleshooting.md Temporarily set the HTTPS_PROXY environment variable to test firewall or proxy configurations when installing npm packages. This is useful if your company network restricts direct access. ```bash # Mac and Linux HTTPS_PROXY=http://proxy.example.com npm install -g elm ``` ```batch # Windows set HTTPS_PROXY=http://proxy.example.com npm install -g elm ``` -------------------------------- ### Elm Bad Recursion Example Source: https://github.com/elm/compiler/blob/master/hints/bad-recursion.md An example of 'bad' recursion in Elm that follows the lambda rule but leads to infinite expansion and a runtime error. This illustrates the limitations of static detection due to the halting problem. ```elm x = (\_ -> x) () + 1 ``` -------------------------------- ### Interactive Elm REPL with `elm repl` Source: https://context7.com/elm/compiler/llms.txt Starts a Read-Eval-Print Loop for evaluating Elm expressions, defining functions, and exploring types. Supports multi-line input, custom types, and module imports. ```elm # Arithmetic and strings > 1 + 1 2 : number > "hello" ++ " world" "hello world" : String # Define a function > increment n = n + 1 : number -> number > increment 41 42 : number # Multi-line recursive function > factorial n = | if n < 1 then | 1 | else | n * factorial (n-1) | : number -> number > factorial 5 120 : number # Custom types and case expressions > type User = Regular String | Visitor String > case Regular "Alice" of | Regular name -> "Welcome back, " ++ name | Visitor name -> "Hello, " ++ name | "Welcome back, Alice" : String ``` -------------------------------- ### Elm 0.15.1 Field Update Syntax Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.16.md Example of the field update syntax in Elm 0.15.1 using the '<-' operator. ```elm { record | x <- 42 } ``` -------------------------------- ### Elm 0.15.1 Field Deletion Syntax Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.16.md Example of field deletion syntax in Elm 0.15.1. ```elm { record - x } ``` -------------------------------- ### Mutually Recursive Type Aliases Example Source: https://github.com/elm/compiler/blob/master/hints/recursive-alias.md Shows how to define mutually recursive type aliases ('Comment' and 'Responses') which require a concrete `type` definition somewhere in the cycle to prevent infinite expansion. ```elm type alias Comment = { message : String, upvotes : Int, downvotes : Int, responses : Responses } type alias Responses = { sortBy : SortBy, responses : List Comment } type SortBy = Time | Score | MostResponses ``` -------------------------------- ### Recursive Type Alias Example (Comment with Responses) Source: https://github.com/elm/compiler/blob/master/hints/recursive-alias.md Illustrates a recursive type alias where a 'Comment' type contains a list of 'Comment' types. This leads to infinite expansion if not handled correctly. ```elm type alias Comment = { message : String, upvotes : Int, downvotes : Int, responses : List Comment } ``` -------------------------------- ### Upvoting a Comment (Obvious Method) Source: https://github.com/elm/compiler/blob/master/hints/recursive-alias.md Provides an example of updating a value within a recursively defined 'Comment' type using the 'obvious' method, which involves unwrapping and re-wrapping the record. ```elm upvote : Comment -> Comment upvote (Comment comment) = Comment { comment | upvotes = 1 + comment.upvotes } ``` -------------------------------- ### Elm 0.16 Field Update Syntax Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.16.md Example of the updated field update syntax in Elm 0.16 using the '=' operator. ```elm { record | x = 42 } ``` -------------------------------- ### Refactored Shadowing Example in Elm Source: https://github.com/elm/compiler/blob/master/hints/shadowing.md Shows how refactoring code can exacerbate shadowing bugs. If not all uses of a shadowed variable are updated, the code may compile but produce incorrect results, as seen when 'name' is expected to be a first name but remains 'Tom'. ```elm viewName : String -> String -> Html msg viewName firstName lastName = ... name ... name ... name ... ``` -------------------------------- ### Initialize a new Elm project with `elm init` Source: https://context7.com/elm/compiler/llms.txt Creates an `elm.json` project manifest and a `src/` directory. Run `elm reactor` afterwards for a live development server. ```bash # Create a new project elm init # Result: creates elm.json and src/ # The generated elm.json for an application looks like: cat elm.json ``` ```json { "type": "application", "source-directories": [ "src" ], "elm-version": "0.19.1", "dependencies": { "direct": { "elm/browser": "1.0.0", "elm/core": "1.0.0", "elm/html": "1.0.0", "elm/json": "1.0.0" }, "indirect": { "elm/time": "1.0.0", "elm/url": "1.0.0", "elm/virtual-dom": "1.0.0" } }, "test-dependencies": { "direct": {}, "indirect": {} } } ``` -------------------------------- ### Replace StartApp with Html.App in Elm 0.17 Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.17.md Shows the transition from using `StartApp.start` in Elm 0.16 to `Html.App.program` in Elm 0.17 for application initialization. ```elm -- 0.16 --------------------------------------- import StartApp import Task app = StartApp.start { init = init, update = update, view = view, inputs = [] } main = app.html port tasks : Signal (Task.Task Never ()) port tasks = app.tasks -- 0.17 --------------------------------------- import Html.App as Html main = Html.program { init = init, update = update, view = view, subscriptions = \_ -> Sub.none } ``` -------------------------------- ### Elm Module System: Import, Alias, and Expose Source: https://context7.com/elm/compiler/llms.txt Demonstrates Elm's module system using `import`, `as` for aliasing, and `exposing` to bring specific names into scope unqualified. Qualified names are the default and recommended practice. ```elm module Main exposing (main) -- Basic import: all references must be qualified import Html -- Alias: shorten long module names import Html.Attributes as A -- Expose specific names unqualified import Html exposing (Html, div, text) import Html.Attributes as A exposing (style) main : Html msg main = div [ A.class "greeting", style "color" "red" ] [ text "Hello, Elm!" ] -- Default imports available in every module (no import needed): -- Basics, List, Maybe, Result, String, Tuple, Debug, Platform, Cmd, Sub ``` -------------------------------- ### Elm Task Output Syntax Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/earlier.md Demonstrates the syntax for running tasks and piping their results back into Elm using `output` and `input`. ```elm output Stream.map toRequest userNames ``` ```elm input results : Stream (Result Http.Error String) input results from Stream.map toRequest userNames ``` -------------------------------- ### Compile Elm with optimizations using `elm make --optimize` Source: https://context7.com/elm/compiler/llms.txt Produces a minification-ready JavaScript bundle by shortening field names and unboxing values. Combine with tools like `uglifyjs` for maximum compression. ```bash # Step 1: compile with --optimize elm make src/Main.elm --optimize --output=elm.js # Step 2: compress and mangle with uglifyjs uglifyjs elm.js \ --compress "pure_funcs=[F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9],pure_getters,keep_fargs=false,unsafe_comps,unsafe" \ | uglifyjs --mangle --output elm.min.js # Print sizes echo "Initial size: $(cat elm.js | wc -c) bytes (elm.js)" echo "Minified size: $(cat elm.min.js | wc -c) bytes (elm.min.js)" echo "Gzipped size: $(cat elm.min.js | gzip -c | wc -c) bytes" # Example output: # Initial size: 148692 bytes (elm.js) # Minified size: 23847 bytes (elm.min.js) # Gzipped size: 8131 bytes ``` -------------------------------- ### Elm Command Line Equivalents (0.19 vs 0.18) Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.19.0.md Maps the new 0.19 Elm command-line commands to their 0.18 counterparts for easy transition. ```bash # 0.19 # 0.18 elm make # elm-make elm repl # elm-repl elm reactor # elm-reactor elm install # elm-package install elm publish # elm-package publish elm bump # elm-package bump elm diff # elm-package diff ``` -------------------------------- ### Elm Task Input Syntax Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/earlier.md Shows how to create new inputs to an Elm program using the `input` keyword, as introduced in Elm 0.15. ```elm input actions : Input Action ``` -------------------------------- ### npm package OS and CPU compatibility Source: https://github.com/elm/compiler/blob/master/installers/npm/PUBLISHING.md This JSON snippet shows how operating system and CPU compatibility is declared in an npm package's metadata. ```json "os": [ "darwin" ], "cpu": [ "arm64" ] ``` -------------------------------- ### Prelude Additions Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/earlier.md Expands the Prelude with additional utility functions, including tuple accessors, currying functions, and list operations. ```Elm fst, snd, curry, uncurry, and a bunch of list functions ``` -------------------------------- ### Update Dependencies in elm-package.json Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.16.md Update the version bounds for your project's dependencies in elm-package.json. Consider using `elm-package install` to manage dependencies. ```json { "dependencies": { "elm-lang/core": "3.0.0 <= v < 4.0.0", "evancz/elm-effects": "2.0.1 <= v < 3.0.0", "evancz/elm-html": "4.0.2 <= v < 5.0.0", "evancz/elm-http": "3.0.0 <= v < 4.0.0", "evancz/elm-markdown": "2.0.0 <= v < 3.0.0", "evancz/elm-svg": "2.0.1 <= v < 3.0.0", "evancz/start-app": "2.0.2 <= v < 3.0.0" }, } ``` -------------------------------- ### Handle Elm Ports in JavaScript Source: https://context7.com/elm/compiler/llms.txt Initialize the Elm application and access its ports object. Use `.subscribe()` to listen for messages from Elm and `.send()` to send messages to Elm. Ensure the Elm app node is correctly selected. ```javascript // JavaScript host page const app = Elm.Main.init({ node: document.getElementById("app") }); // Listen for Elm → JS messages app.ports.storeToLocalStorage.subscribe(function(value) { localStorage.setItem("myKey", value); }); // Send JS → Elm app.ports.receiveFromLocalStorage.send(localStorage.getItem("myKey") || ""); ``` -------------------------------- ### Recursive Function Definition in Elm Source: https://github.com/elm/compiler/blob/master/hints/bad-recursion.md Example of a standard recursive function. Elm's evaluation strategy allows direct substitution of function calls with their definitions. ```elm factorial : Int -> Int factorial n = if n <= 0 then 1 else n * factorial (n - 1) ``` -------------------------------- ### Display PATH Environment Variable Source: https://github.com/elm/compiler/blob/master/installers/linux/README.md View the directories your system searches for executable commands by echoing the PATH environment variable. ```bash echo $PATH ``` -------------------------------- ### Elm Runtime System Distribution Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/earlier.md Starting from version 0.3.0, the Elm JavaScript runtime is distributed with the compiler. Ensure you serve the runtime file that matches the compiler version used. ```text elm-runtime-0.3.0.js ``` -------------------------------- ### Elm Type Aliases for Basic Types Source: https://github.com/elm/compiler/blob/master/hints/recursive-alias.md Demonstrates creating type aliases as shorthands for existing types like Float. These do not create new types. ```elm type alias Time = Float type alias Degree = Float type alias Weight = Float ``` -------------------------------- ### Publishing a beta release of the Elm npm package Source: https://github.com/elm/compiler/blob/master/installers/npm/PUBLISHING.md This command publishes a beta version of the Elm npm package using the 'beta' tag. This allows for testing before a final release. ```bash npm publish --tag beta ``` -------------------------------- ### Elm Type Aliases, Records, and Functional Updates Source: https://context7.com/elm/compiler/llms.txt Shows how to use `type alias` for shorthand and define records. Demonstrates record field accessors, functional update syntax for creating modified copies, and efficient DOM rendering with `Html.Keyed` and `Html.Lazy`. ```elm module Profile exposing (Student, viewStudents) import Html exposing (Html, li, text, ul) import Html.Keyed as Keyed import Html.Lazy exposing (lazy) type alias Student = { name : String , age : Int , gpa : Float } type SortOrder = ByName | ByAge | ByGPA -- Constructor generated automatically: Student "Alice" 20 3.8 alice : Student alice = Student "Alice" 20 3.8 -- Functional update: create modified copy without mutation olderAlice : Student olderAlice = { alice | age = alice.age + 1 } -- Field accessor used directly as a function viewStudents : SortOrder -> List Student -> Html msg viewStudents order students = let sorted = case order of ByName -> List.sortBy .name students ByAge -> List.sortBy .age students ByGPA -> List.sortBy .gpa students in -- Html.Keyed + Html.Lazy for efficient DOM diffing Keyed.ul [] (List.map ( s -> ( s.name, lazy viewStudent s )) sorted) viewStudent : Student -> Html msg viewStudent s = li [] [ text (s.name ++ " — GPA: " ++ String.fromFloat s.gpa) ] ``` -------------------------------- ### Compile and Optimize Elm Code with UglifyJS Source: https://github.com/elm/compiler/blob/master/hints/optimize.md Compile your Elm application with the `--optimize` flag and then process the output JavaScript with `uglifyjs` for further compression and mangling. This two-step process is necessary for optimal results. ```bash elm make src/Main.elm --optimize --output=elm.js uglifyjs elm.js --compress "pure_funcs=[F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9],pure_getters,keep_fargs=false,unsafe_comps,unsafe" | uglifyjs --mangle --output elm.min.js ``` -------------------------------- ### Infinite Type Error Example Source: https://github.com/elm/compiler/blob/master/hints/infinite-type.md This code demonstrates a common cause of infinite type errors: a typo leading to unintended self-recursion. The extra 's' in 'incrementNumbers' causes it to call itself instead of the intended 'incrementNumber' function. ```elm incrementNumbers list = List.map incrementNumbers list incrementNumber n = n + 1 ``` -------------------------------- ### Compile an Elm application with `elm make` Source: https://context7.com/elm/compiler/llms.txt Compiles Elm source files to JavaScript or a standalone HTML file. Use `--output` to specify the artifact type. Defaults to `index.html` if no output is specified. ```bash # Compile to a standalone HTML page (default) elm make src/Main.elm # Compile to a JS file for embedding elm make src/Main.elm --output=main.js # Compile multiple entry points elm make src/PageA.elm src/PageB.elm --output=bundle.js # Expected output on success: # Success! Compiled 1 module. # # index.html ──────────────────────────────── 30 kb ``` -------------------------------- ### Define User-Defined Operator (Removed) Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.19.0.md In Elm 0.19.0, defining custom operators like the example shown is no longer permitted. Functions can still be defined, but they must have human-readable names. This change aims to improve code clarity and maintainability. ```elm |-~-> : (a -> a1_1 -> a3) -> (a2 -> a1_1) -> a -> a2 -> a3 ``` -------------------------------- ### Update elm-package.json dependencies for Elm 0.17 Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.17.md Modify the 'dependencies' and 'elm-version' fields in elm-package.json to reflect the updated core packages and the new Elm version constraint. After updating 'elm-version' manually, it's recommended to clear 'dependencies' and reinstall them one by one using 'elm package install'. ```json { "version": "1.0.0", "summary": "let people do a cool thing in a fun way", "repository": "https://github.com/user/project.git", "license": "BSD3", "source-directories": [ "src" ], "exposed-modules": [], "dependencies": { "elm-lang/core": "4.0.0 <= v < 5.0.0", "elm-lang/html": "1.0.0 <= v < 2.0.0", "evancz/elm-http": "3.0.1 <= v < 4.0.0", "evancz/elm-markdown": "3.0.0 <= v < 4.0.0" }, "elm-version": "0.17.0 <= v < 0.18.0" } ``` -------------------------------- ### Application `elm.json` Baseline Source: https://github.com/elm/compiler/blob/master/docs/elm.json/application.md This is a standard `elm.json` configuration for most Elm applications, specifying type, source directories, Elm version, and dependencies. ```json { "type": "application", "source-directories": [ "src" ], "elm-version": "0.19.1", "dependencies": { "direct": { "elm/browser": "1.0.0", "elm/core": "1.0.0", "elm/html": "1.0.0", "elm/json": "1.0.0" }, "indirect": { "elm/time": "1.0.0", "elm/url": "1.0.0", "elm/virtual-dom": "1.0.0" } }, "test-dependencies": { "direct": {}, "indirect": {} } } ``` -------------------------------- ### Publishing a binary npm package Source: https://github.com/elm/compiler/blob/master/installers/npm/PUBLISHING.md This command publishes a scoped npm package with public access. It is necessary for scoped packages which are private by default. ```bash npm publish --access=public ``` -------------------------------- ### Checking npm distribution tags Source: https://github.com/elm/compiler/blob/master/installers/npm/PUBLISHING.md These commands are used to verify the distribution tags for the Elm npm package, ensuring that 'latest' and 'beta' tags are correctly set. ```bash npm dist-tags ls elm ``` ```bash npm install elm@beta --ignore-scripts ``` -------------------------------- ### Evaluate Basic Expressions in REPL Source: https://github.com/elm/compiler/blob/master/hints/repl.md Use the REPL to evaluate simple arithmetic and string operations. The REPL displays the result and its type. ```elm > 1 + 1 2 : number ``` ```elm > "hello" ++ "world" "helloworld" : String ``` -------------------------------- ### Display PATH Variable on Mac and Linux Source: https://github.com/elm/compiler/blob/master/installers/npm/troubleshooting.md View the directories your system searches for executable commands. This helps in understanding where the 'elm' command should be located. ```bash $ echo $PATH /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin ``` -------------------------------- ### Elm Port Syntax Revision Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/earlier.md Illustrates the revised port syntax in Elm 0.15, using `foreign input` and `foreign output` keywords for clarity. ```elm foreign input dbResults : Stream String foreign output dbRequests : Stream String foreign output dbRequests = Stream.map toRequest userNames ``` -------------------------------- ### Optimizing Record Sorting with Html.Lazy and Html.Keyed Source: https://github.com/elm/compiler/blob/master/hints/comparing-records.md Employ `Html.Lazy` and `Html.Keyed` to optimize the rendering of sorted lists. `Keyed.ul` helps in efficiently reordering DOM nodes, while `lazy` prevents unnecessary re-renders of unchanged elements. ```elm import Html exposing (..) import Html.Lazy exposing (lazy) import Html.Keyed as Keyed type Order = Name | Age | GPA type alias Student = { name : String , age : Int , gpa : Float } viewStudents : Order -> List Student -> Html msg viewStudents order students = let orderlyStudents = case order of Name -> List.sortBy .name students Age -> List.sortBy .age students GPA -> List.sortBy .gpa students in Keyed.ul [] (List.map viewKeyedStudent orderlyStudents) viewKeyedStudent : Student -> (String, Html msg) viewKeyedStudent student = ( student.name, lazy viewStudent student ) viewStudent : Student -> Html msg viewStudent student = li [] [ text student.name ] ``` -------------------------------- ### Module declaration syntax change from 0.16 to 0.17 Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.17.md The syntax for declaring modules has changed. In 0.16, 'module Queue (..) where' was used, while in 0.17, it is 'module Queue exposing (..)' to explicitly define what is exposed. ```elm module Queue (..) where ``` ```elm module Queue exposing (..) ``` -------------------------------- ### Package `elm.json` Structure Source: https://github.com/elm/compiler/blob/master/docs/elm.json/package.md This is a typical `elm.json` file for a package, defining its metadata, exposed modules, and dependencies. ```json { "type": "package", "name": "elm/json", "summary": "Encode and decode JSON values", "license": "BSD-3-Clause", "version": "1.0.0", "exposed-modules": [ "Json.Decode", "Json.Encode" ], "elm-version": "0.19.0 <= v < 0.20.0", "dependencies": { "elm/core": "1.0.0 <= v < 2.0.0" }, "test-dependencies": {} } ``` -------------------------------- ### Elm npm package optional dependencies Source: https://github.com/elm/compiler/blob/master/installers/npm/PUBLISHING.md This JSON snippet illustrates how the main Elm npm package declares its dependency on platform-specific binary packages using optional dependencies. ```json "@elm_binaries/darwin_arm64": "0.19.1-0", "@elm_binaries/darwin_x64": "0.19.1-0", "@elm_binaries/linux_arm64": "0.19.1-0", ... ``` -------------------------------- ### JavaScript Interop Initialization Changes in Elm 0.17 Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.17.md Compares the JavaScript methods for embedding, running fullscreen, and running Elm as a worker in versions 0.16 and 0.17. ```javascript Elm.embed(Elm.Main, someNode); ``` ```javascript Elm.Main.embed(someNode); ``` ```javascript Elm.fullscreen(Elm.Main); ``` ```javascript Elm.Main.fullscreen(); ``` ```javascript Elm.worker(Elm.Main); ``` ```javascript Elm.Main.worker(); ``` -------------------------------- ### New Keyboard Events in Elm Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/earlier.md Introduces support for raw keyboard events via the Keyboard.Raw module. ```Elm Keyboard.Raw ``` -------------------------------- ### Package elm.json Configuration Source: https://context7.com/elm/compiler/llms.txt Package `elm.json` specifies version ranges for dependencies, lists exposed modules, and requires an OSI-approved license. Semantic versioning is enforced by `elm diff` and `elm bump`. ```json { "type": "package", "name": "elm/json", "summary": "Encode and decode JSON values", "license": "BSD-3-Clause", "version": "1.1.3", "exposed-modules": [ "Json.Decode", "Json.Encode" ], "elm-version": "0.19.0 <= v < 0.20.0", "dependencies": { "elm/core": "1.0.0 <= v < 2.0.0" }, "test-dependencies": {} } ``` -------------------------------- ### Basic Qualified Import in Elm Source: https://github.com/elm/compiler/blob/master/hints/imports.md Use this to import a module and access its contents using the module name as a prefix. This is the most straightforward way to avoid naming conflicts. ```elm import Html main = Html.div [] [] ``` -------------------------------- ### Ensure Non-Empty Lists by Unrolling Source: https://github.com/elm/compiler/blob/master/hints/missing-patterns.md An alternative to returning `Maybe` for lists is to 'unroll' the list by requiring the first element as an argument. This makes it impossible to call the function with an empty list. ```elm last : a -> List a -> a last first rest = case rest of [] -> first newFirst :: newRest -> last newFirst newRest ``` -------------------------------- ### New Basic Libraries Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/earlier.md Adds two fundamental libraries, Data.Char and Data.Maybe, to the Elm ecosystem. ```Elm Data.Char ``` ```Elm Data.Maybe ``` -------------------------------- ### Exposing All Contents of a Module in Elm Source: https://github.com/elm/compiler/blob/master/hints/imports.md Use 'exposing (..)' to import all values and types from a module without qualification. Use this sparingly to avoid naming collisions and maintain code clarity. ```elm import Html exposing ( .. ) import Html.Attributes exposing (style) main : Html msg main = div [ style "color" "red" ] [ text "Hello!" ] ``` -------------------------------- ### Define and Use Values in REPL Source: https://github.com/elm/compiler/blob/master/hints/repl.md Define variables and functions directly in the REPL. The REPL will show the type of the definition or the result of function calls. ```elm > fortyTwo = 42 42 : number ``` ```elm > increment n = n + 1 : number -> number ``` ```elm > increment 41 42 : number ``` -------------------------------- ### Show API Differences Between Elm Package Versions Source: https://context7.com/elm/compiler/llms.txt Use `elm diff` to compare public APIs of two package versions. This helps verify semantic versioning compliance before publishing. The output indicates MINOR, MAJOR, or no changes. ```bash elm diff elm/json 1.0.0 1.1.3 ``` -------------------------------- ### Handle Ambiguous Imports in Elm Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.19.1.md When importing modules, ensure that exposed names do not conflict with names from `Basics`. Use qualified names like `Html.min` or `Regex.never` to resolve ambiguity. ```elm import Html exposing (min) import Regex exposing (never) x = min y = never ``` -------------------------------- ### Publishing a New Package Version in Elm Source: https://context7.com/elm/compiler/llms.txt Use `elm bump` to automatically detect and update the version for a patch release, then use `elm publish` to upload the new version to the package repository. ```bash # Publish a new patch version after fixing a bug elm bump # detects PATCH change, updates version to 1.1.4 elm publish # uploads to package.elm-lang.org ``` -------------------------------- ### Elm 0.15.1 Record Constructor with Field Update Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.16.md Demonstrates record constructors that add fields in Elm 0.15.1, generating a function. ```elm type alias Named r = { r | name : String } -- generates a function like this: -- Named : String -> r -> Named r ``` -------------------------------- ### Combined Modules (Using Unique Identifiers) Source: https://github.com/elm/compiler/blob/master/hints/import-cycles.md This approach breaks recursion by using unique identifiers (UserId) instead of direct references. This allows types to be defined without cyclic dependencies and enables them to be separated into different modules. ```elm module GoodCombination exposing (..) import Dict type alias Comment = { comment : String , author : UserId } type alias UserId = String type alias AllComments = Dict.Dict UserId (List Comment) ``` -------------------------------- ### Elm Type Alias for Record Shorthand Source: https://github.com/elm/compiler/blob/master/hints/recursive-alias.md Shows a common use case for type aliases: creating a shorthand for a record structure to improve readability. ```elm type alias Person = { name : String, age : Int, height : Float } ``` -------------------------------- ### Optimize Elm Code with a Shell Script Source: https://github.com/elm/compiler/blob/master/hints/optimize.md A shell script to automate the Elm compilation and `uglifyjs` optimization process. It compiles the Elm code, then compresses and mangles it, and finally prints the initial, minified, and gzipped sizes of the output files. ```bash #!/bin/sh set -e js="elm.js" min="elm.min.js" elm make --optimize --output=$js $@ uglifyjs $js --compress "pure_funcs=[F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9],pure_getters,keep_fargs=false,unsafe_comps,unsafe" | uglifyjs --mangle --output $min echo "Initial size: $(cat $js | wc -c) bytes ($js)" echo "Minified size:$(cat $min | wc -c) bytes ($min)" echo "Gzipped size: $(cat $min | gzip -c | wc -c) bytes" ``` -------------------------------- ### Infinite Recursion with Values in Elm Source: https://github.com/elm/compiler/blob/master/hints/bad-recursion.md Demonstrates a problematic value definition that leads to infinite expansion. The compiler detects this to prevent runtime freezes. ```elm x = x + 1 ``` -------------------------------- ### Redefine Signal.(~) with Signal.map2 Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.16.md If you are combining a large number of signals, you can redefine the equivalent of `Signal.(~)` using `Signal.map2` and `Signal.(<|)`. ```elm andMap : Signal (a -> b) -> Signal a -> Signal b andMap = Signal.map2 (<|) ``` -------------------------------- ### Rename Effects to Cmd in Elm 0.17 Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.17.md Illustrates the renaming of `Effects` to `Cmd` and the corresponding import change from `evancz/elm-effects` to `Platform.Cmd` in Elm 0.17. ```elm -- 0.16 update : Action -> Model -> (Model, Effects Action) update action model = case action of RequestMore -> (model, getRandomGif model.topic) NewGif maybeUrl -> ( Model model.topic (Maybe.withDefault model.gifUrl maybeUrl) , Effects.none ) -- 0.17 update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of RequestMore -> ( model, getRandomGif model.topic ) NewGif maybeUrl -> ( Model model.topic (Maybe.withDefault model.gifUrl maybeUrl) , Cmd.none ) ``` -------------------------------- ### Replace List Range Syntax Source: https://github.com/elm/compiler/blob/master/docs/upgrade-instructions/0.18.md The `[1..9]` syntax for list ranges has been removed. Use `List.range` instead. ```elm -- Replace [1..9] with List.range 1 9 ``` -------------------------------- ### Use Wrapper Modules for Typed IDs in Elm Source: https://context7.com/elm/compiler/llms.txt Employ wrapper modules for typed IDs that require `Dict` keys. This pattern encapsulates the ID generation and dictionary management logic. ```elm -- Use a wrapper module for typed IDs that need Dict keys module UserId exposing (Id, Table, empty, get, add) import Dict exposing (Dict) type Id = Id Int type Table info = Table Int (Dict Int info) empty : Table info empty = Table 0 Dict.empty get : Id -> Table info -> Maybe info get (Id id) (Table _ dict) = Dict.get id dict add : info -> Table info -> ( Table info, Id ) add info (Table nextId dict) = ( Table (nextId + 1) (Dict.insert nextId info dict) , Id nextId ) ```