This slide is about... - What is Elm? - Why is Elm great? - For web-app developers × Type systems × Useful tools/libraries × For game developers × For FP developers
a = model(1) b = model(1) updateC = function() { c = a.value + b.value } a.onChange(updateC) b.onChange(updateC) updateC() I know the observer pattern!
About Elm - born in Apr 2012 - ver 0.15 - designed by Evan Czaplicki (Prezi) - http://elm-lang.org/ - https://groups.google.com/forum/#! forum/elm-discuss
Hello, world! import Html exposing (..) import Html.Attributes exposing (..) main : Html main = ul [class "grocery-list"] [ li [] [text "Pamplemousse"] , li [] [text "Ananas"] , li [] [text "Jus d'orange"] ] ul : List Attribute → List Html → Html li : List Attribute → List Html → Html class : String → Attribute
Signals import Html exposing (..) import Mouse main : Signal Html main = Signal.map (\p -> text (toString p)) Mouse.position Mouse.position : Signal (Int, Int) Signal.map : (a → b) → Signal a → Signal b toString : a → String
Signals import Html exposing (..) import Mouse main : Signal Html main = Signal.map (\count -> text (toString count)) countClick countClick : Signal Int countClick = Signal.foldp (\clk count -> count + 1) 0 Mouse.clicks Mouse.clicks : Signal () Signal.foldp : (a → b → b) → b → Signal a → Signal b
You might think FRP looks like... keydown timestamp errors fullname ajax formData firstName lastName enter letter tabIndex errorCount ok messages html click submit ok error reset inputs
The Elm Architecture -- MODEL type alias Model = { ... } -- UPDATE type Action = Reset | ... update : Action -> Model -> Model update action model = case action of Reset -> ... ... -- VIEW view : Model -> Html view model = ...
Model -- MODEL type alias Model = { tasks : List Task , field : String , uid : Int , visibility : String } type alias Task = { description : String , completed : Bool , editing : Bool , id : Int }
Update update : Action -> Model -> Model update action model = case action of NoOp -> model Add -> { model | uid <- model.uid + 1, field <- "", tasks <- if String.isEmpty model.field then model.tasks else model.tasks ++ [newTask model.field model.uid] } Delete id -> { model | tasks <- List.filter (\t -> t.id /= id) model.tasks } Check id isCompleted -> let updateTask t = if t.id == id then { t | completed <- isCompleted } else t in { model | tasks <- List.map updateTask model.tasks } ...
Main main : Signal Html main = Signal.map (view actions.address) model model : Signal Model model = Signal.foldp update initialModel actions.signal actions : Signal.Mailbox Action actions = Signal.mailbox NoOp
Stateful components? updateButton : ButtonAction -> ButtonState -> ButtonState updateButton action state = case action of Click -> { state | count <- state.count + 1 } update : Action -> Model -> Model update action model = case action of ButtonA a -> { model | buttonA <- updateButton a model.buttonA } ButtonB b -> { model | buttonB <- updateButton b model.buttonB } Main.elm Button.elm