elm

реактивное программирование в браузере

Синтаксис

  • Диалект Haskell
  • Отсутствие побочных эффектов
  • Специальный синтаксис для union-типов
  • Специальный синтаксис для записей
  • Интероперабельность с JavaScript

Union-типы

type Maybe a = Just a | Nothing

String.toInt : String -> Maybe Int


toMonth : String -> Maybe Int
toMonth rawString =
    case String.toInt rawString of
      Nothing ->
          Nothing

      Just n ->
          if n > 0 && n <= 12 then Just n else Nothing

Union-типы

type List a = Empty | Node a (List a)

sum : List Int -> Int
sum xs =
    case xs of
      Empty ->
          0

      Node first rest ->
          first + sum rest

Record-типы

point = { x = 3, y = 4 }       -- create a record

point.x                        -- access field
map .x [point,{x=0,y=0}]       -- field access function

{ point - x }                  -- remove field
{ point | z = 12 }             -- add field
{ point - x | z = point.x }    -- rename field
{ point - x | x = 6 }          -- update field

{ point | x <- 6 }             -- nicer way to update a field
{ point | x <- point.x + 1
        , y <- point.y + 1 }   -- batch update fields

dist {x,y} = sqrt (x^2 + y^2)  -- pattern matching on fields
\{x,y} -> (x,y)

lib = { id x = x }             -- polymorphic fields
(lib.id 42 == 42)
(lib.id [] == [])

type alias Location = { line:Int, column:Int }

JavaScript-интероперабельность

port addUser : Signal (String, UserRecord)
myapp.ports.addUser.send([
    "Tom",
    { age: 32, job: "lumberjack" }
]);

myapp.ports.addUser.subscribe(subscriber);

function subscriber(user) {
 // ...
}

Реактивное программирование

map : (a -> b) -> Signal a -> Signal b

filter : (a -> Bool) -> a -> Signal a -> Signal a

merge : Signal a -> Signal a -> Signal a

foldp : (a -> s -> s) -> s -> Signal a -> Signal s

Реактивное программирование

import Html exposing (div, button, text)
import Html.Events exposing (onClick)
import StartApp

main =
  StartApp.start { model = model, view = view, update = update }

model = 0

view address model =
  div []
    [ button [ onClick address Decrement ] [ text "-" ]
    , div [] [ text (toString model) ]
    , button [ onClick address Increment ] [ text "+" ]
    ]

type Action = Increment | Decrement

update action model =
  case action of
    Increment -> model + 1
    Decrement -> model - 1

Спасибо!

Elm

By Ilya Lakhin