Introduction to Elm
Evan Czaplicki

Создан для фронтенда
Компилируется в JS
Строгая типизация
Хороший DX и отсутствие ошибок в рантайме
Производительность

Синтаксис
Литералы
-- Boolean
True : Bool
False : Bool
42 : number -- Int or Float depending on usage
3.14 : Float
'a' : Char
"abc" : String
-- multi-line String
"""
This is useful for holding JSON or other
content that has "quotation marks".
"""If выражения
if powerLevel > 9000 then "OVER 9000!!!" else "meh"
if key == 40 then
n + 1
else if key == 38 then
n - 1
else
nPattern matching
case maybe of
Just xs -> xs
Nothing -> []
case xs of
hd::tl -> Just (hd,tl)
[] -> Nothing
case n of
0 -> 1
1 -> 1
_ -> fib (n-1) + fib (n-2)Функции
Объявление
square n =
n^2
hypotenuse a b =
sqrt (square a + square b)
distance (a,b) (x,y) =
hypotenuse (a-x) (b-y)
square =
\n -> n^2
squares =
List.map (\n -> n^2) (List.range 1 100)Композиция
viewNames1 names =
String.join ", " (List.sort names)
viewNames2 names =
names
|> List.sort
|> String.join ", "
leftAligned (monospace (fromString "code"))
leftAligned <| monospace <| fromString "code"
fn1 = not << isEven << round << sqrt
fn2 = sqrt >> round >> isEven >> notТипы
answer : Int
answer =
42
factorial : Int -> Int
factorial n =
List.product [1..n]
distance : { x : Float, y : Float } -> Float
distance {x,y} =
sqrt (x^2 + y^2)Структуры данных
Иммутабельность
Списки
list = [1, 2, 3, 4]
listFromRange = [1..4]
listByAppending = [1, 2] ++ [3, 4]
listByPrepending = 1 :: 2 :: 3 :: 4 :: []
list = [1,2,3,4]
-- [1,2,3,4] : List number
filteredList = List.filter (\n -> n > 2) list
-- [3,4] : List number
firstElement = List.head list
-- Just 1 : Maybe.Maybe number
restOfTheElements = List.tail list
-- Just [2,3,4] : Maybe.Maybe (List number)Массивы
list = [1,2,3,4]
-- [1,2,3,4] : List number
filteredList = List.filter (\n -> n > 2) list
-- [3,4] : List number
firstElement = List.head list
-- Just 1 : Maybe.Maybe number
restOfTheElements = List.tail list
-- Just [2,3,4] : Maybe.Maybe (List number)Set
import Set
set1 = Set.fromList [1,2,3,4,3,2,1]
-- Set.fromList [1,2,3,4] : Set.Set number
set2 = Set.fromList [3,4,5,6]
-- Set.fromList [3,4,5,6] : Set.Set number
intersection = Set.intersect set1 set2
-- Set.fromList [3,4] : Set.Set number
union = Set.union set1 set2
-- Set.fromList [1,2,3,4,5,6] : Set.Set number
differences = Set.diff set1 set2
-- Set.fromList [1,2] : Set.Set numberСловари
import Dict
users = Dict.fromList \
[ ("dennis", { email = "mail@dennisreimann.de"}) \
, ("otherdude", { email = "otherdude@example.org"}) \
]
usernames = Dict.keys users
-- ["dennis","otherdude"] : List String
userRecords = Dict.values users
-- [{ email = "mail@dennisreimann.de" },{ email = "otherdude@example.org" }] : List { email : String }
dennis = Dict.get "dennis" users
-- Just { email = "mail@dennisreimann.de " } : Maybe.Maybe { email : String }Tuple
-- tuple without type definition
coordinates = (53.1201749, 8.5962037)
-- tuple with type definition
area : (Int, Int)
area = (42, 23)
-- tuple with type alias
type alias IsValid = Bool
type alias Message = String
type alias ValidationResult = (IsValid, Message)
success : ValidationResult
success = (True, "All is good.")
error : ValidationResult
error = (False, "Something went wrong.")Records
-- record without type definition
coordinate =
{ latitude = 53.1201749
, longitude = 8.5962037
}
-- record with type definition
area : { width : Int, height : Int }
area =
{ width = 42
, height = 23
}
-- record with type definition via type alias
type alias User =
{ login : String
, isAdmin : Bool
}
alice : User
alice =
{ login = "alice"
, isAdmin = False
}
bob : User
bob =
{ login = "bob"
, isAdmin = True
}Нет undefined / null
Maybe
> type Maybe a = Nothing | Just a
> Nothing
Nothing : Maybe a
> Just
<function> : a -> Maybe a
> Just "hello"
Just "hello" : Maybe String
> Just 1.618
Just 1.618 : Maybe Float
getTeenAge : User -> Maybe Int
getTeenAge user =
case user.age of
Nothing ->
Nothing
Just age ->
if 13 <= age && age <= 18 then
Just age
else
NothingИнтересные идеи
Сообщения об ошибках

Package system
Forced semver

Applications
Model-View-Update
import Html exposing (..)
-- MODEL
type alias Model = { ... }
-- UPDATE
type Msg = Reset | ...
update : Msg -> Model -> Model
update msg model =
case msg of
Reset -> ...
...
-- VIEW
view : Model -> Html Msg
view model =
...Usage in production

Как внедрить
- Have an advocate
- Start small
- Fix a problem
- Write Elm code
Минусы
- Экспериментальный
- Нет четкого плана развития
- Opinionated
- Проект одного человека
Вопросы?
Introduction to Elm
By Pavel Trehubau
Introduction to Elm
- 349