Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Elm introduction

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for Yannick Gladow Yannick Gladow
June 27, 2017
36

Elm introduction

Avatar for Yannick Gladow

Yannick Gladow

June 27, 2017
Tweet

Transcript

  1. Key Features • user-friendly • maintanable • purely functional •

    static types • compiles to js • claims: no runtime errors • can interact with regular js
  2. User-focused Design • addresses frontend developers • gradual learning •

    easy to get started • easy to get into fp • minimalistic
  3. Named Functions half : Float -> Float half n =

    n / 2 divide : Float -> Float -> Float divide x y = x / y half 2.0 divide 5.0 2.0
  4. Anonymous Functions \n -> n / 2 <function> : Float

    -> Float \x -> (\y -> x / y) <function> : Float -> Float -> Float (\x -> (\y -> x / y)) 3 -- \y -> 3 / y <function> : Float -> Float
  5. -- value x = 3 -- tuples aTuple = ("hello",

    123, [ 3, 2, 1 ]) -- lists listOfString = [ "A", "B", "C" ] anotherList = 1 :: 2 :: 3 :: 4 :: [] -- generic datatype reverseList : List a -> List a reverseList a = reverse a
  6. hasLongName : { lastName : String, firstName : String }

    -> Bool hasLongName user = String.length user.lastName > 3
  7. hasLongName : { lastName : String, firstName : String }

    -> Bool hasLongName user = String.length user.lastName > 3 type alias FirstName = String type alias User = { lastName : String , firstName : FirstName } hasLongName : User -> Boolean
  8. • like objects in java/js { name : String, age:

    Int } littleTobi = { name = "Tobi" , age = 12 } -- { name = "Tobi", age = 12 } : { age : number, name : String }
  9. -- access records littleTobi.name -- "Tobi" .name littleTobi -- "Tobi"

    -- { b | name : a } -> a changeName : String -> User -> User changeName newName user = { user | name = newName }
  10. -- type alias for records type alias User = {

    name : String, age: Int } User : String -> Int -> User tom = User "Tom" 33
  11. -- pattern match under50 : { a | age :

    number } -> Bool under50 { age } = age < 50 -- extensible records type alias Named a = { a | name : String }
  12. Union types - Sum types type User = Anonymous |

    Named String > Anonymous Anonymous : User > Named <function> : String -> User
  13. -- adt type Msg = Increment | Decrement update :

    Msg -> Int -> Int update msg count = case msg of Increment -> count + 1 Decrement -> count - 1
  14. -- tuple myTuple = ("A", "B", "C") (a,b,_) = myTuple

    isABC : ( String, String, String ) -> Bool isABC tuple = case tuple of ( "A", "B", "C" ) -> True _ -> False
  15. -- list matchingLists : List a -> String matchingLists list

    = case list of [] -> "empty" [_] -> "one" [a,b] -> "two" a::b::_ -> "a, b and more"
  16. type Maybe a = Nothing | Just a -- optional

    fields type alias User = { name : String, age : Maybe Int } -- partial functions head : List a -> Maybe a head list = case list of x :: xs -> Just x [] -> Nothing
  17. getOrElse : Maybe a -> a -> a getOrElse maybe

    default = case maybe of Just a -> a Nothing -> default
  18. TEA

  19. • Model type alias Model = { ... } •

    Update type Msg = Update | ... update : Msg -> Model -> Model • View view : Model -> Html Msg
  20. Update -- UPDATE type Msg = Increment | Decrement update

    : Msg -> Model -> Model update msg model = case msg of Increment -> model + 1 Decrement -> model - 1
  21. View import Html exposing (Html, button, div, text) import Html.Events

    exposing (onClick) -- VIEW view : Model -> Html Msg view model = div [] [ button [ onClick Decrement ] [ text "-" ] , div [] [ text (toString model) ] , button [ onClick Increment ] [ text "+" ] ]
  22. -- VIEW view : Model -> Html Msg view model

    = div [] [ button [ onClick MorePlease ] [ text "More Please!" ] , img [ src model ] [] ]
  23. -- UPDATE type Msg = MorePlease | NewGif (Result Http.Error

    String) update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of MorePlease -> ( model, getRandomGif ) NewGif (Ok newUrl) -> ( newUrl, Cmd.none ) NewGif (Err _) -> ( model, Cmd.none )
  24. -- HTTP getRandomGif : Cmd Msg getRandomGif = let url

    = "https://api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=cats" in Http.send NewGif (Http.get url decodeGifUrl) decodeGifUrl : Decode.Decoder String decodeGifUrl = Decode.at [ "data", "image_url" ] Decode.string
  25. New Model type alias Model = { tags : List

    Tag , inputTag : Tag , email : String , searchResults : List SearchResult , route : Route } type Route = Home | NotFoundRoute
  26. On Location Change OnLocationChange location -> let newRoute = parseLocation

    location in ( { model | route = newRoute }, Cmd.none )
  27. New View view : Model -> Html Msg view model

    = div [] [ page model ] page : Model -> Html Msg page model = case model.route of Home -> Page.HomePage model NotFoundRoute -> Page.NotFound
  28. Route Handler matchers : Parser (Route -> a) a matchers

    = oneOf [ map Home top —- / , map Home (s "tags") —- /tags ] parseLocation : Location -> Route parseLocation location = case (parseHash matchers location) of Just route -> route Nothing -> NotFoundRoute
  29. pageHeader : Html msg pageHeader = let green = Css.rgb

    30 104 30 white = Css.rgb 255 255 255 in header [ class "content-header" , styles [ Css.textAlign Css.center , Css.backgroundColor green , Css.color white , Css.height (Css.px 50) , Css.marginTop (Css.px 10) ] ] [ text "HEADER" ]
  30. $ elm-package diff evancz/elm-html 1.0.0 2.0.0 Comparing evancz/elm-html 1.0.0 to

    2.0.0... This is a MAJOR change. ------ Changes to module Html.Attributes - MAJOR ------ Changed: - colspan : String -> Attribute + colspan : Int -> Attribute - rowspan : String -> Attribute + rowspan : Int -> Attribute
  31. multiply2 : Int -> Int multiply2 i = i *

    2 multiply2 "2" The argument to function `multiply2` is causing a mismatch. 6| multiply2 "2" ^^^ Function `multiply2` is expecting the argument to be: Int But it is: String
  32. -- Maybe type --functor map : (a -> b) ->

    Maybe a -> Maybe b -- applicative map2 : (a -> b -> value) -> Maybe a -> Maybe b -> Maybe value -- monad andThen : (a -> Maybe b) -> Maybe a -> Maybe b -- traversable sequence : List (Task x a) -> Task x (List a)
  33. insert : comparable -> v -> Dict comparable v ->

    Dict comparable v -- haskell insert :: Ord k => k -> a -> Map k a -> Map k a • Ord k is typeclass • comparable is compiler magic • can not define own instance for custom datatype • Hint: Only ints, floats, chars, strings, lists, and tuples are comparable.