- Hello World
- Comments
- Modules
- Tools
- HTML Embedding
- Primitives
- Collections
- Functions
- Type Annotation
- Operators
- Control Statements
- purely functional language
- statically typed
- no runtime exceptions
- outperforms most popular rendering libraries
- package manager
- built-in tooling
- HTML, CSS, JavaScript interoperability
- clean syntax
- I like frontend again...
File HelloWorld.elm:
import Html exposing (h1, text)
import Html.Attributes exposing (id)
-- Hello world example
main =
h1 [id "hw"] [text "Hello World!"]-- Single line comment
{-
Multi-line comment
-}-- Defining a module, exports everything by default
module Mymodule where
-- Export only specified entities
module Mymodule (Type, value) where
-- Export all or specific states of type
module Mymodule
( Error(Forbidden, Timeout)
, Stuff(..)
) where
type Error
= Forbidden String
| Timeout String
| NotFound String-- qualified imports
import String -- String.toUpper, String.repeat
import String as Str -- Str.toUpper, Str.repeat
-- unqualified imports
import Mymodule exposing (..) -- Error, Stuff
import Mymodule exposing ( Error ) -- Error
import Mymodule exposing ( Error(..) ) -- Error, Forbidden, Timeout
import Mymodule exposing ( Error(Forbidden) ) -- Error, Forbiddenelm repl / elm-repl
Import required modules
> import ListGet function signature
> List.map
<function> : (a -> b) -> List a -> List b
> (++)
<function> : appendable -> appendable -> appendableElm expressions return resulting value and type
> 1 + 1
2 : numberBackslash \ is for multi-line expressions
> fn a b = \
| a + b
<function> : number -> number -> number
elm make / elm-make
# Default compilation
elm make HelloWorld.elm -> elm.js
# Custom name
$ elm make HelloWorld.elm --output hw.js
# Custom name and multiple files
$ elm make HelloWorld.elm MyModule.elm --output hw.js
# With warnings
$ elm make HelloWorld.elm --warn
# To HTML
$ elm make HelloWorld.elm --output hw.htmlelm package / elm-package
# Install a package
$ elm-package install evancz/elm-html
# Specific version
$ elm-package install evancz/elm-html 1.0.0
# Diff two versions
$ elm-package diff evancz/virtual-dom 2.0.0 2.1.0
Comparing evancz/virtual-dom 2.0.0 to 2.1.0...
This is a MINOR change.
------ Changes to module VirtualDom - MINOR ------
Added:
attributeNS : String -> String -> String -> VirtualDom.PropertyVersioning matters.
MAJOR.MINOR.PATCH
PATCH- the API is the same, no risk of breaking codeMINOR- values have been added, existing values are unchangedMAJOR- existing values have been changed or removed
elm-package.json
source-directories- array of directories to look up for project source code inside the working directoryexposed-modules- array of directories to expose publishing modules that are not meant for users
Publishing a package requires well documented code.
git tag -a 1.0.0 -m "initial release"
git push --tags
elm-package publishUpdate a package
elm-package bumpRunning fullscreen
elm-make HelloWorld.elm -> elm.js
<script type="text/javascript" src="elm.js"></script>
<script type="text/javascript">
Elm.fullscreen(Elm.HelloWorld);
</script>Embed explicitly in a html element
<script type="text/javascript" src="elm.js"></script>
<script type="text/javascript">
var elmHolder = document.getElementById('hw-wrapper');
Elm.embed(Elm.HelloWorld, elmHolder);
</script>Run without graphics
Elm.worker(Elm.HelloWorld);Numeric types are number and Float, number represents both Int and Float:
> 1
1 : number
> 2.0
2 : Float
> truncate 0.1
0 : Int
> truncate 1
1 : IntString types are char and String
> 'a'
'a' : Char
> "Hello"
"Hello" : StringMulti-line string
"""
Hello
World
"""Single quotes are for char only
> 'ab'
-- SYNTAX PROBLEM --
> "ab"
"ab" : String> True
True : Bool
> False
False : Boolcomparable - ints, floats, chars, strings, lists, tuples
appendable - strings, lists, text.
Kind of dynamic types are represented as a, b, c etc. meaning that you can pass any value, even functions
A list holds a collection of related values separated by commas and enclosed in
square brackets. All the values in a list must have the same type:
> []
[] : List a
> [1,2,3]
[1,2,3] : List number
> ["a", "b", "c"]
["a","b","c"] : List StringWays to create a list
> [1..4]
> [1,2,3,4]
> 1 :: [2,3,4]
> 1 :: 2 :: 3 :: 4 :: []Tuples package two or more expressions into a single expression. The type of a tuple records the number of components and each of their types.
> (1, "2", True)
(1,"2",True) : ( number, String, Bool )Also possible, put as many commas as you'll have values inside a tuple
> (,,,) 1 True 'a' []
(1,True,'a',[]) : ( number, Bool, Char, List a )Records are immutable. A record is a collection of key/value pairs,
similar to objects in JavaScript or dictionary in Python
myRecord =
{ style = "Blue",
number = 1,
isCool = True
}Accessing records
> myRecord.style
"Blue" : String
> .style myRecord
"Blue" : StringUpdating records returns a new record
> updatedRecord = { myRecord | style = "Red", number = 10, isCool = False }
> myRecord.style
"Blue" : String
> updatedRecord.style
"Red" : StringBasics
-- function name | arguments names = function body
sum a b = a + bAll functions in Elm are curried by default.
If you have a function of 2 arguments, it takes one argument and returns a function that takes another argument:
-- Both are equal
myFunction arg1 arg2
((myFunction arg1) arg2)
-- Partial application
> minus x y = (-) x y
<function> : number -> number -> number
> minus1 = minus 1
<function> : number -> number
> minus 11
-10 : numberAlso known as lambdas
-- (\function arguments -> function body)
-- parenthesized, content starts with backslash
(\n -> n < 0)
(\x y -> x * y)Functions that placed between two arguments and enclosed in backticks ` are called infix
-- Normal
> min 1 2
1 : number
-- Prefix
> 1 `min` 2
1 : numberFunctions that placed in front of arguments while enclosed in parentheses are called prefix
-- Normally you would do this
> "abcde" ++ "fghij"
"abcdefghij" : String
-- Infix
> (++) "abcde" "fghij"
"abcdefghij" : StringCustom types
type Movement = Right | Left | Stop Elm, like most ML dialects, automatically infers most types.
-- function name : 1st arg type -> 2nd arg type -> return type
fnc : Int -> List -> IntExample below is read as function that takes an a value and returns a b value, list of a values returns a list of b values
map: (a -> b) -> List a -> List bPattern matching on record fields
-- Requires the argument with x and y fields
multiply {x,y} =
x * yAnnotating records
coordinates : { x : Float, y : Float }
coordinates =
{ x = 0,
y = 0
} In a nutshell Elm operators are functions.
| Operator | Description | Type hint |
|---|---|---|
+ |
addition | number -> number -> number |
- |
subtraction | number -> number -> number |
* |
multiplication | number -> number -> number |
/ |
floating point division | Float -> Float -> Float |
// |
integer division, discard the reminder | Int -> Int -> Int |
^ |
exponentiation | number -> number -> number |
% |
modulo | Int -> Int -> Int |
| Operator | Description | Type hint |
|---|---|---|
and |
bitwise AND | Int -> Int -> Int |
or |
bitwise OR | Int -> Int -> Int |
xor |
biwise XOR | Int -> Int -> Int |
| Operator | Description | Type hint |
|---|---|---|
== |
equal | comparable -> comparable -> Bool |
/= |
not equal | comparable -> comparable -> Bool |
< |
less than | comparable -> comparable -> Bool |
<= |
less than or equal | comparable -> comparable -> Bool |
> |
greater than | comparable -> comparable -> Bool |
>= |
greater than or equal | comparable -> comparable -> Bool |
| Operator | Description | Type hint |
|---|---|---|
&& |
logical and | Bool -> Bool -> Bool |
| ` | ` | |
not |
logical not | Bool |
| Operator | Description | Type hint |
|---|---|---|
| `< | ` | backward (pipe) function application `f < |
| ` | >` | forward (pipe) function application `x |
<< |
composes functions into one, arguments first applied to the function from the right side | (b -> c) -> (a -> b) -> a -> c |
>> |
same as before except arguments first applied to the function from the left side | (a -> b) -> (b -> c) -> a -> c |
| Operator | Description | Type hints |
|---|---|---|
++ |
put appendable things together | appendable -> appendable -> appendable |
:: |
add an element to the front of a list | a -> List a -> List a |
All the branches of an if need to match so that no matter which one we take, we get back the same type of value overall.
if a < 1 then
"It's zero"
else
"Non-zero"
-- Multi-line.
if y > 0 then
"Greater"
else if x /= 0 then
"Not equals"
else
"silence"Elm does not have the notion of “truthiness”.
The condition must evaluate to True or False, and nothing else.
> if 1 then "nope" else "nope again"
- TYPE MISMATCH --