06/07/2016 - Cambridge DDD Nights
Why use statically typed pure Functional languages?
Elm is a Functional Language for interactive applications.
e.g. Clock Ticks, Websockets
Keep Elm not irreversibly tied to Javascript, everything that will require platform-specific code is broken off into Platform.
app.ports.check.subscribe(function(word) {
var suggestions = spellCheck(word); app.ports.suggestions.send(suggestions);
});
type Tile
= Door Size
| Column
| BackGround BackGroundTile
| Shadow ShadowTile
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
type alias Model =
{ input : String
, messages : List String
}
type alias Model =
{ input : String
, messages : List String
}
type alias Model =
{ input : String
, messages : List String
}
init : (Model, Cmd Msg)
init =
(Model "" [], Cmd.none)
init : (Model, Cmd Msg)
init =
(Model "" [], Cmd.none)
type Msg
= Input String
| Send
| NewMessage String
type Msg
= Input String
| Send
| NewMessage String
Message is a Union Type
update : Msg -> Model -> (Model, Cmd Msg) update msg {input, messages} = case msg of Input newInput -> (Model newInput messages, Cmd.none) Send -> (Model "" messages, WebSocket.send "ws://echo.websocket.org" input) NewMessage str -> (Model input (str :: messages), Cmd.none)
update : Msg -> Model -> (Model, Cmd Msg) update msg {input, messages} = case msg of Input newInput -> (Model newInput messages, Cmd.none) Send -> (Model "" messages, WebSocket.send "ws://echo.websocket.org" input) NewMessage str -> (Model input (str :: messages), Cmd.none)
Pattern Matching
update : Msg -> Model -> (Model, Cmd Msg) update msg {input, messages} = case msg of Input newInput -> (Model newInput messages, Cmd.none) Send -> (Model "" messages, WebSocket.send "ws://echo.websocket.org" input) NewMessage str -> (Model input (str :: messages), Cmd.none)
Constructor
Side Effects
update : Msg -> Model -> (Model, Cmd Msg) update msg {input, messages} = case msg of Input newInput -> (Model newInput messages, Cmd.none) Send -> (Model "" messages, WebSocket.send "ws://echo.websocket.org" input) NewMessage str -> (Model input (str :: messages), Cmd.none)
subscriptions : Model -> Sub Msg
subscriptions model =
WebSocket.listen "ws://echo.websocket.org" NewMessage
view : Model -> Html Msg view model = div [] [ div [] (List.map viewMessage model.messages) , input [onInput Input] [] , button [onClick Send] [text "Send"] ] viewMessage : String -> Html msg viewMessage msg = div [] [ text msg ]
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
Wiring up the Program
(which is good if it fits, less if it doesn't. You don't have to conform to a specific architecture in Purescript/Haskell)