Kevin Greene
A talk kind of about Elm
!+[]+!![] == "2"var getInt = function(x) {
if (x)
return 1;
else
return "1";
}
// Let's blame the intern
// But we've all written thisvar getInt = function(x,y,z) {
if (x) {
var intermediateStep = otherFunctionCall(y);
var valueWeCareAbout = intermediateStep.deeply.nested.map
return processNumbers(valueWeCareAbout,z)
}
else
return defaultProcess(y,z);
}> getInt x = if x then 1 else "0"
-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm
The branches of this `if` produce different types of values.
4| getInt x = if x then 1 else "0"
^^^^^^^^^^^^^^^^^^^^
The `then` branch has type:
number
But the `else` branch is:
String
Hint: These need to match so that no matter which branch we take, we always get
back the same type of value.
type Color
= RGB Int Int Int
| HSL Int Int Int
| Hex String
nameColor x =
case x of
RGB r g b ->
"blue"
Hex hexString ->
"green"
This `case` does not have branches for all possibilities.
10|> case x of
11|> RGB r g b ->
12|> "blue"
13|> Hex hexString ->
14|> "green"
You need to account for the following values:
Main.HSL _ _ _
Add a branch to cover this pattern!interface HSL {
kind: "hsl";
h: number;
s: number;
l: number;
}
interface RGB {
kind: "rgb";
r: number;
g: number;
b: number;
}
type Color = HSL | RGB
class HSL {
h: number;
s: number;
l: number;
}
class RGB {
r: number;
g: number;
b: number;
}
type Color = HSL | RGB;
kind of
kind of
(from evancz/elm-todomvc)
type alias Model =
{ entries : List Entry
, field : String
, uid : Int
, visibility : String
}
type alias Entry =
{ description : String
, completed : Bool
, editing : Bool
, id : Int
}
emptyModel : Model
emptyModel =
{ entries = []
, visibility = "All"
, field = ""
, uid = 0
}
newEntry : String -> Int -> Entry
newEntry desc id =
{ description = desc
, completed = False
, editing = False
, id = id
}
type Msg
= NoOp
| UpdateField String
| Addview : Model -> Html Msg
view model =
div
[ class "todomvc-wrapper"
, style [ ( "visibility", "hidden" ) ]
]
[ section
[ class "todoapp" ]
[ viewInput model.field
, viewEntries model.visibility model.entries
, viewControls model.visibility model.entries
]
, infoFooter
]
viewInput : String -> Html Msg
viewInput task =
header
[ class "header" ]
[ h1 [] [ text "todos" ]
, input
[ class "new-todo"
, placeholder "What needs to be done?"
, autofocus True
, value task
, name "newTodo"
, onInput UpdateField
, onEnter Add
]
[]
]-- How we update our Model on a given Msg?
update : Msg -> Model -> Model
update msg model =
case msg of
NoOp ->
model
Add ->
{ model
| uid = model.uid + 1
, field = ""
, entries =
if String.isEmpty model.field then
model.entries
else
model.entries ++ [ newEntry model.field model.uid ]
}
UpdateField str ->
{ model | field = str }main =
Html.beginnerProgram
{ model = model
, view = view
, update = update
}but still faster overall
entryDecoder: Decoder Entry
entryDecoder =
object3 Entry
("description" := string)
("id" := int)
("completed" := bool)
fetchData =
Http.get entryDecoder "https://todos.com"
|> Task.mapError toString
|> Task.perform ErrorOccurred DataFetched
(once again, types are pretty cool)
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (toString model) ]
, button [ onClick Increment ] [ text "+" ]
]
Elm
div(
List.empty,
List(
button(
List(onClick(Decrement)),
List(text("-"))
),
div(
List.empty,
List(text (model.toString))
),
button(
List(onClick(Increment)),
List(text("+"))
)
)
)Scala
(the other kind)
css =
(stylesheet << namespace "flashcard")
[ body
[ minWidth (px 500)
]
, h1 [ textAlign center ]
, (.) Flashcard
[ color (hex "888888")
, height cardHeight
, width cardWidth
, textAlign center
, border3 (px 3) solid (hex "333333")
, marginLeft auto
, marginRight auto
]
, (.) FlashcardContainer
[ marginLeft auto
, marginRight auto
, width (px 500)
]
, (.) NextButton
[ margin (px 50) ]
]
div [ class [ FlashcardCss.Flashcard ] ]
[ h1 [] [ flashcardTextArea flashcard display ]
]