https://github.com/rtfeldman/elm-workshop
welcome to elm!
please follow these instructions to get set up:
<ul class="highway"> <li>danger</li> <li>zone</li></ul>
ulclass="highway"
li li
text text“danger” “zone”
<ul class="highway"> <li>danger</li> <li>zone</li></ul>
ulclass="highway"
li li
text text“danger” “zone”
ul [ class "highway" ] [ li [] [ text "danger" ], li [] [ text "zone" ] ]
<ul class="highway"> <li>danger</li> <li>zone</li></ul>
ulclass="highway"
li li
text text“danger” “zone”
ul [ class "highway" ] [ li [] [ text "danger" ] , li [] [ text "zone" ] ]
Exercise: resolve the TODOs in part1/Main.elm
<ul class="highway"> <li>danger</li> <li>zone</li></ul>
ul [ class "highway" ] [ li [] [ text "danger" ] , li [] [ text "zone" ] ]
pluralize singular plural quantity = if quantity == 1 then toString quantity ++ " " ++ singular else toString quantity ++ " " ++ plural
pluralize singular plural quantity = if quantity == 1 then toString quantity ++ " " ++ singular else toString quantity ++ " " ++ plural
code duplication
pluralize singular plural quantity = let quantityStr = toString quantity
prefix = quantityStr ++ " " in if quantity == 1 then prefix ++ singular else prefix ++ plural
pluralize singular plural quantity = let quantityStr = toString quantity
prefix = quantityStr ++ " " in if quantity == 1 then prefix ++ singular else prefix ++ plural
let-expression
pluralize singular plural quantity = let quantityStr = toString quantity
prefix = quantityStr ++ " " in if quantity == 1 then prefix ++ singular else prefix ++ plural
inaccessible inoutside scope
pluralize singular plural quantity = let quantityStr = toString quantity
prefix = quantityStr ++ " " in if quantity == 1 then prefix ++ singular else prefix ++ plural
entire expressionevaluates to this
record = { name = "thing", x = 1, y = 3 }
tuple = ( "thing", 1, 3 )
a tuple is shorthand for a record
record = { name = "thing", x = 1, y = 3 }
tuple = ( "thing", 1, 3 )
( name, x, y ) = ( "thing", 1, 3 )
tuple destructuring
record = { name = "thing", x = 1, y = 3 }
tuple = ( "thing", 1, 3 )
( name, x, y ) = ( "thing", 1, 3 )
name == "thing"x == 1
Records Tuples Lists
mixedcontents
mixedcontents
uniformcontents
fixedlength
fixed length
variable length
Exercise: resolve the TODOs in part2/Main.elm
record = { x = 4, y = 2 }
record.x == 4record.y == 2
toString 99 == "99"
negate (5 + 9) == -14 toString 99 ++ " balloons" == "99 balloons"
function pluralizeLeaves(quantity) { return pluralize("leaf", "leaves", quantity);}
pluralizeLeaves quantity = pluralize "leaf" "leaves" quantity
function pluralizeLeaves(quantity) { return pluralize("leaf", "leaves", quantity);}
pluralizeLeaves quantity = pluralize "leaf" "leaves" quantity
pluralizeLeaves = pluralize "leaf" "leaves"
function pluralizeLeaf(plural, quantity) { return pluralize("leaf", plural, quantity);}
pluralizeLeaf plural quantity = pluralize "leaf" plural quantity
pluralizeLeaf = pluralize "leaf"
List.filter (\num -> num >= 2) [ 1, 2, 3 ]
== [ 2, 3 ]
isKeepable num = num >= 2
List.filter isKeepable [ 1, 2, 3 ]
== [ 2, 3 ]
{ operation = "SHOW_MORE", data = 10}
update msg model = if msg.operation == "SHOW_MORE" then { maxResults = model.maxResults + msg.data } else model
update msg model = if msg.operation == "SHOW_MORE" then { maxResults = model.maxResults + msg.data } else model
{ operation = "SHOW_MORE", data = 10}
what if there are other fields in the model?
update msg model = if msg.operation == "SHOW_MORE" then { maxResults = model.maxResults + msg.data } else model
update msg model = if msg.operation == "SHOW_MORE" then { model | maxResults = model.maxResults + msg.data } else model
viewupdate Model
Msg Htmlh1 [] [ text "ElmHub" ]
{ query = "tutorial"
, results = []
}
{ operation = "DELETE_BY_ID"
, data = 2
}
Elm Runtime
Exercise: resolve the TODOs in part3/Main.elmElm: (\foo -> foo + 1)
JS: (function(foo) { return foo + 1 })
{ animals | cats = animals.cats + 1 }
List.filter (\num -> num >= 2) [ 1, 2, 3 ]
== [ 2, 3 ]
type alias Model =
{ query : String
, results : List SearchResult
}
type alias SearchResult =
{ id : Int
, name : String
, stars : Int
}
type alias Msg =
{ operation : String
, data : Int
}
view : Model -> Html Msg
view model =
button [ onClick { operation = "RESET", data = "all" } ]
[ text "Reset All" ]
view : Model -> Html Msg
view model =
button [ onClick { operation = "RESET", data = "all" } ]
[ text "Reset All" ]
type alias Msg =
{ operation : String
, data : Int
}
update : Msg -> Model -> Model
update msg model =
type alias Msg =
{ operation : String
, data : Int
}
update : Msg -> Model -> Model
update msg model =
if msg.operation == "DELETE_BY_ID" then -- remove from modelelse if msg.operation == "LOAD_RESULTS" then -- load more resultselse -- default branch
case msg.operation of "DELETE_BY_ID" -> -- remove from model
"LOAD_RESULTS" -> -- load more results
_ -> -- default branch
case currentSorting of Ascending -> -- sort ascending here
Descending -> -- sort descending here
Randomized -> -- sort randomized here
type Sorting = Ascending String | Descending String | Randomized
type
function
functionconstant
String -> Sorting
case currentSorting of Ascending colName -> -- sort ascending here
Descending colName -> -- sort descending here
Randomized -> -- sort randomized here
type alias Msg = { operation : String , data : Int }
{ operation = "DELETE_BY_ID" , data = 3 }
{ operation = "SET_QUERY" , data = "tutorial" }
case msg of SetQuery query -> -- set query in the model here
DeleteById id -> -- delete the result with this id here
type Msg = SetQuery String | DeleteById Int
function (String -> Sorting)
Exercise: resolve the TODOs in part5/Main.elm
type Sorting = Ascending String | Descending String | Randomized
type
constantfunction (String -> Sorting)
String.toInt "42" == Ok 42String.toInt "halibut" == Err "umm halibut is not an int"
type Result = Ok somethingGood Err somethingBad
List.filter (\num -> num < 5) [ 2, 4, 6, 8 ]
List.reverse (List.filter (\num -> num < 5) [ 2, 4, 6, 8 ])
[ 2, 4, 6, 8 ] |> List.filter (\num -> num < 5) |> List.reverse
List.reverse (List.filter (\num -> num < 5) [ 2, 4, 6, 8 ])
[ 2, 4, 6, 8 ] |> List.filter (\num -> num < 5) |> List.reverse |> List.map negate
List.reverse (List.filter (\num -> num < 5) [ 2, 4, 6, 8 ])
[ 2, 4, 6, 8 ] |> List.filter (\num -> num < 5) |> List.reverse |> List.map negate |> List.head
List.reverse (List.filter (\num -> num < 5) [ 2, 4, 6, 8 ])
decodeString (list int) "[1, 2, 3]"
== Ok [ 1, 2, 3 ]
"[1, 2, 3]" |> decodeString (list int)
== Ok [ 1, 2, 3 ]
makeGameState score playing = { score = score, playing = playing }
decoder = ???
decodeString decoder """{"score": 5.5, "playing": true}"""
== Ok { score = 5.5, playing = True }
makeGameState score playing = { score = score, playing = playing }
decoder = decode makeGameState |> required "score" float |> required "playing" bool
decodeString decoder """{"score": 5.5, "playing": true}"""
== Ok { score = 5.5, playing = True }
makeGameState score playing = { score = score, playing = playing }
decoder = decode makeGameState |> required "score" float |> required "playing" bool
decodeString decoder """{"score": 5.5, "playing": true}"""
== Ok { score = 5.5, playing = True }
makeGameState score playing = { score = score, playing = playing }
decoder = decode makeGameState |> required "score" float |> required "playing" bool
decodeString decoder """{"score": 5.5, "playing": true}"""
== Ok { score = 5.5, playing = True }
type alias GameState = { score : Float, playing : Bool }
makeGameState : Float -> Bool -> GameStatemakeGameState score playing = { score = score, playing = playing }
type alias GameState = { score : Float, playing : Bool }
GameState : Float -> Bool -> GameState
makeGameState : Float -> Bool -> GameStatemakeGameState score playing = { score = score, playing = playing }
type alias GameState = { score : Float, playing : Bool }
GameState : Float -> Bool -> GameState
makeGameState : Float -> Bool -> GameStatemakeGameState score playing = { score = score, playing = playing }
makeGameState 2.3 True == GameState 2.3 True
type alias GameState = { score : Float, playing : Bool }
decoder = decode GameState |> required "score" float |> required "playing" bool
decodeString decoder """{"score": 5.5, "playing": true}"""
== Ok { score = 5.5, playing = True }
type alias GameState = { score : Float, playing : Bool }
decoder = decode GameState |> required "score" float |> required "playing" bool
decodeString decoder """{"score": 5.5, "playing": true}"""
== Ok { score = 5.5, playing = True }
type alias GameState = { score : Float, playing : Bool }
decoder = decode GameState |> required "score" float |> required "playing" bool
Exercise: resolve the TODOs in part6/Main.elm
viewupdate Model
Msg
h1 [] [ text "ElmHub" ]
{ query = "tutorial"
, results = []
}
{ operation = "DELETE_BY_ID"
, data = 2
}
Elm Runtime
Html
viewupdate Model
Msg
h1 [] [ text "ElmHub" ]
{ query = "tutorial"
, results = []
}
DeleteById 2
Elm Runtime
Html Msg
viewupdate Model
Msg Html Msg
Elm Runtime
Cmd MsgSetGreeting 5
pickGreeting : List String -> Cmd Msg
viewupdate Model
Msg Html Msg
Elm Runtime
Cmd MsgSetGreeting 5
pickGreeting : List String -> Cmd Msg
viewupdate
Msg Html Msg
Elm Runtime
Cmd MsgSetGreeting 5
pickGreeting : List String -> Cmd Msg
( model, pickGreeting greetings )
Model
Task.perform (\err -> ShowError err) (\json -> SetJson json) (Http.getString "https://api.github.com?q=blah")
Task Cmdtranslate failure into a Msg
translate success into a Msg
Task.perform ShowError SetJson (Http.getString "https://api.github.com?q=blah")
Task Cmdtranslate failure into a Msg
translate success into a Msg
Http.getString "https://api.github.com?q=blah" |> Task.perform ShowError SetJson
Task Cmdtranslate failure into a Msg
translate success into a Msg
cmd : Cmd Msgcmd = Http.getString "https://api.github.com?q=blah" |> Task.perform ShowError SetJson
Task Cmdtranslate failure into a Msg
translate success into a Msg
-- success gives you a StringHttp.getString url
-- success gives you a SearchResultHttp.get searchResultDecoder url
Exercise: resolve the TODOs in part7/Main.elm
cmd : Cmd Msgcmd = Http.getString "https://api.github.com?q=blah" |> Task.perform ShowError SetJson
-- success gives you a SearchResultHttp.get searchResultDecoder url
Top Related