---
# System prepended metadata

title: Elm純函數式語言初探(一) - 介紹及安裝
tags: [Elm]

---

---
title: Elm純函數式語言初探(一) - 介紹及安裝
description: Elm是用於開發web apps的強型態純函數式語言，能編譯出高性能表現的JavaScript。
# image: https://hackmd.io/screenshot.png
tags: Elm
# robots: noindex, nofollow
langs: zh-Hant
---

# Elm純函數式語言初探(一) - 介紹及安裝
Elm是用於開發web apps的強型態純函數式語言，能編譯出高性能表現的JavaScript。根據官方公佈的[測試結果][blazing-fast-html-round-two]，能讓runtime的執行速度比目前主流框架的Angular及React還快。不僅如此，編譯出來的JavaScript的檔案大小也比三大主流框架較小([Small Assets][small-assets-without-the-headache])，讓瀏覽器有更快的下載速度和更快的頁面加載。

在官方網站列出首要特點是**無運行時例外錯誤(No Runtime Exceptions)**。Elm的作者Evan Czaplicki認為[編譯器應該是開發人員的助手][compilers-as-assistants]而不是對手。在編譯期間，採用型別推斷(type inference)來偵測資料型別的錯誤，並在錯誤訊息中顯示型別差異(type diffs)，描述了實際的資料型別並給於預期的資料型別的提示。除此之外，其他的種類的錯誤也有提供人性化的錯誤訊息。

Elm有自己的[API package管理系統][package.elm-lang.org]，有強制的語義版本控制(Enforced Semantic Versioning)，能避免API釋出的新版本差異影響到目前開發的專案。

Elm擁[有JavaScript互操作性][JavaScript Interop]，和React一樣能接管單個HTML Node，所以現有的專案能部分嵌入Elm編譯的JavaScript代碼。

## 安裝Elm
Mac及Windows有獨立的安裝程式，也可以使用[npm][elm]來安裝。

```
npm install -g elm
```

目前主流的代碼編輯器都有支援Elm的擴充功能，如VSCode有[vscode-elm]的擴充功能。

Elm有幾個的終端指令可以使用：
- `elm repl`：開啟互動式編程環境(REPL)
- `elm reactor`：建立本地伺服器(http://localhost:8000)，在瀏覽器上啟用檔案瀏覽器，開啟Elm檔案會編譯並看到結果
- `elm make`：可以將Elm檔案編譯為HTML或JavaScript
- `elm install`：安裝Elm packages

詳細說明請查閱[官方文件說明][install]。

## 程式碼範例
官方網站的[介紹](https://guide.elm-lang.org/)提供一個[簡單計數器][simple counter]的線上範例。`update`和`view`是完全分離的，以聲明方式描述HTML，Elm負責處理DOM。
```elm
module Main exposing (main)

import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)


type alias Model =
    { count : Int }


initialModel : Model
initialModel =
    { count = 0 }


type Msg
    = Increment
    | Decrement


update : Msg -> Model -> Model
update msg model =
    case msg of
        Increment ->
            { model | count = model.count + 1 }

        Decrement ->
            { model | count = model.count - 1 }


view : Model -> Html Msg
view model =
    div []
        [ button [ onClick Increment ] [ text "+1" ]
        , div [] [ text <| String.fromInt model.count ]
        , button [ onClick Decrement ] [ text "-1" ]
        ]


main : Program () Model Msg
main =
    Browser.sandbox
        { init = initialModel
        , view = view
        , update = update
        }
```


[blazing-fast-html-round-two]: https://elm-lang.org/blog/blazing-fast-html-round-two
[small-assets-without-the-headache]: https://elm-lang.org/blog/small-assets-without-the-headache
[compilers-as-assistants]: https://elm-lang.org/blog/compilers-as-
[package.elm-lang.org]: https://package.elm-lang.org
[JavaScript Interop]: https://guide.elm-lang.org/interop
[install]: https://guide.elm-lang.org/install.html
[elm]: https://www.npmjs.com/package/
[vscode-elm]: https://marketplace.visualstudio.com/items?itemName=sbrink.elm
[simple counter]: https://ellie-app.com/new
