iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 6
0
Modern Web

學會Elm寫前端系列 第 6

06 認識Elm裡的類別(type system)

  • 分享至 

  • xImage
  •  

終於要說到types了

Elm裡的type system相對haskell做了不少簡化,一個是 type alias ,一個是 union type
。先來說說type好了: 以下你可以在你的elm-repl 或是線上的elm-repl試試。
例子來自 elm guide

> "hello"
"hello" : String

> not True
False : Bool

> round 3.1415
3 : Int

> [ "Alice", "Bob" ]
[ "Alice", "Bob" ] : List String

> \n -> n / 2
<function> : Float -> Float

不管是什麼,每一個東西都有type,你沒有寫type,elm會幫你推測,你大概要什麼。所以你自己的程式,要把type加上去,叫 type annotations

half : Float -> Float
half n =
  n / 2

divide : Float -> Float -> Float
divide x y =
  x / y

type alias

如果elm 內建的沒有你要的type 呢?或是一直重複打字也很麻煩:

hasBio : { name : String, bio : String, pic : String } -> Bool
hasBio user =
  String.length user.bio > 

像這個 hasBio 是一個record type, 但是要自己打這麼長嗎? 可以改寫成:

type alias User = 
{ name : String
  , bio : String
  , pic : String
  }

hasBio : User -> Bool
hasBio user =
  String.length user.bio > 0

這樣就不會那麼麻煩了。

Union Type

union types 又是在幹麼的呢? 我覺得最好的例子就是elm 內建的Maybe

type Maybe a = Just a | Nothing

那什麼時候會用到這個union type 呢?

完整的code在這裡

type Msg
    = SetQuery String
    | DeleteById Int

-- other code here

update : Msg -> Model -> Model
update msg model =
    case msg of
        SetQuery input ->
            { model | query = input }
        DeleteById id ->
            { model |
              results = List.filter (\result -> result.id /= id) model.results
            }

通常我們會和 case expression 一起使用,如上,在 union type Msg 裡,我們有 SetQuery
DeleteById 我們可以把它當成是一個 functionSetQuery 可以吃一個 String , 而
DeleteById 可以吃一個 Int

viewSearchResult : SearchResult -> Html Msg
viewSearchResult result =
    li []
        [ span [ class "star-count" ] [ text (toString result.stars) ]
        , a [ href ("https://github.com/" ++ result.name), target "_blank" ]
            [ text result.name ]
        , button
            [ class "hide-result"
            , onClick ( DeleteById result.id )
            ]
            [ text "X" ]
        ]

這裡,在這個按鈕裡, onClick 有看到 DeleteById 嗎? 你如果在elm-repl裡試試

> import Html.Events exposing (..)

> onClick
<function> : msg -> Html.Attribute msg

> type Msg = SetQuery String | DeleteById Int

> onClick (DeleteById 4)
{ key = "EVENT", realKey = "click", value = { options = { stopPropagation = False, preventDefault = False }, decoder = <decoder> } }
    : Html.Attribute Repl.Msg

這裡的 msg 是可以給我們自行定義的,我們有定義一個 Msg 是union type,所以按下去後,會傳出這個 msg, msg -> Html.Attribute msg 我們可以看做是 a -> Html.Attribute a 這個 a
是你自己定義的也好,或是內建的 String 也好,總之是要一樣的type
啊,我個人覺得document寫得不太好,一下小寫的msg, 一下大寫的MSG,如果對type想要更瞭解,推薦學習
haskell (學完後,所有的type system language都不是問題了。)

如果還是不太能理解,我們之後實做有機會再多說一點,總之,記得要有type annotations,自己定義的只有兩種,一個是type
alias, 一個是union type。


上一篇
05 來喝茶吧,認識 The Elm Architecture
下一篇
07 如何在Elm裡讀Json?
系列文
學會Elm寫前端30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言