This marks the end of our crash course programming in Elm. We have all we need to use Elm as our implementation language for the rest of our course topics. For your projects, you may want to poke around and learn more; some pointers below.
There is a start-app
library which hides most of "plumbing" involved with using signals for basic purposes. So far, we have been programming explicitly with signals to emphasize the functional reactive paradigm.
As you develop larger applications (i.e. your course project), you will want to consider using these more full-featured libraries. At that point, consult the Elm Architecture for guidance.
The core libraries Graphics.Element
and Graphics.Collage
provide an API for a small (and somewhat low-level) subset of the full HTML (+ CSS + SVG) specifications. Additional libraries — including elm-html
, elm-svg
, and markdown
— provide more complete, "thin wrapper" access to the entire target language. Although the former libraries are no longer the preferred way to write HTML applications in modern Elm (times change quickly with a young language!), we started by using them nonetheless.
See LocalStorage.html
for an example of how to use JavaScript to save information across visits to a webpage (on a per-domain basis).
Outgoing ports are used to communicate from Elm to JavaScript, and incoming ports are used to communicate from JavaScript to Elm.
Define an Elm module CountPageVisits.elm
with port
s, which act like "external" Signal
s:
module CountPageVisits where
import Graphics.Element exposing (show)
import Mouse
port count : Signal Int
port reset : Signal ()
port reset = Mouse.clicks
main =
Signal.map (\i -> show ("Counter: " ++ toString i)) count
In a JavaScript file Ports.js
, load the Elm module Elm.CountPageVisits
, and send
to its incoming ports and subscribe
to its outgoing ports:
function getCount() { ... }
function incCount() { ... }
function resetCount() { ... }
function getAndIncCount() { ... }
var myApp = Elm.fullscreen(Elm.CountPageVisits, {
count: getAndIncCount()
});
myApp.ports.reset.subscribe(function(event) {
resetCount();
myApp.ports.count.send(getAndIncCount());
});
Compile the Elm module to JavaScript...
% elm-make CountPageVisits.elm --output=CountPageVisits.js
... and then put the pieces together in CountPageVisits.html
.
So far, we have been using only the core package libraries. There is also a growing number of community packages. Using them is easy. Just define an elm-package.json
file that specifies which libraries you want to import.
Say we want to use this HTML package. Add the location of this package to an otherwise boilerplate elm-package.json
file (take a look at one generated from elm-make
):
{
"version": "1.0.0",
"summary": "helpful summary of your project, less than 80 characters",
"repository": "https://github.com/user/project.git",
"license": "BSD3",
"source-directories": [
"."
],
"exposed-modules": [],
"dependencies": {
"elm-lang/core": "3.0.0 <= v < 4.0.0"
"evancz/elm-html": "4.0.2 <= v < 5.0.0"
},
"elm-version": "0.16.0 <= v < 0.17.0"
}
The names of the Elm modules exported by this package are listed at the top of its documentation page. You can also click the "View Source" on the documentation page and view the elm-package.json
file.
Now, import
and use the library in an Elm file HtmlTest.elm
...
module HtmlTest where
import Html (..)
main =
toElement 500 500
<| div []
<| [ h1 [] [text "Header 1"]
, ol [] [li [] [text "one"], li [] [text "two"], li [] [text "three"]]
, ul [] [li [] [text "one"], li [] [text "two"], li [] [text "three"]]
, button [] [text "click me"]
, input [] [text "type here"]
]
... and appropriate versions of the libraries will be downloaded locally into an elm-stuff/
directory:
% ls
HtmlTest.elm elm-package.json
% elm-make HtmlTest.elm --output=HtmlTest.html
Some new packages are needed. Here is the upgrade plan.
Install:
elm-lang/core 1.1.0
evancz/elm-html 2.0.0
evancz/virtual-dom 1.2.2
Do you approve of this plan? (y/n) y
Downloading elm-lang/core
Downloading evancz/elm-html
Downloading evancz/virtual-dom
Packages configured successfully!
Compiled 38 files
Successfully generated HtmlTest.html
% ls
HtmlTest.elm HtmlTest.html elm-package.json elm-stuff
In subsequent homework and project assignments, you may submit an elm-package.json
to declare any community libraries you wish to use.
And if you end up building useful libraries of your own, considering publishing them!
Read this if and when you need to do more with the outside world.