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

Elm introduction

Yannick Gladow
June 27, 2017
26

Elm introduction

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.