2016-10-04 100 views
4

試圖在JS中學習Elm並且在強類型和靜態類型語言中經驗不多,我發現主要困難圍繞類型語法(以及在Elm中通常有用的類型) 。不幸的是,在這方面我沒有發現這些文檔非常有用。瞭解Elm中的類型

我若簡單的例子這裏:http://elm-lang.org/examples/buttons,線:

type Msg = Increment | Decrement 

聯合類型Msg定義爲 「是」 或者IncrementDecrement。它似乎暗示IncrementDecrement也是類型。他們究竟是什麼? (它們在示例中沒有定義,也不是預定義的類型)。

然後,它們在view函數中用作參數onClick。現在,他們似乎表現得像一種「信息」(無論這意味着什麼)。在JS中,這可能會通過在每種情況下爲(可變)變量賦值來實現 - 當然這不可能是Elm方式。那麼,類型的工作方式是否與不可變性相關?

view功能:

view model = 
    div [] 
    [ button [ onClick Decrement ] [ text "-" ] 
    , div [] [ text (toString model) ] 
    , button [ onClick Increment ] [ text "+" ] 
    ] 

我想,這可能會打開一個更廣闊的主題(如果有人可以指向有用的鏈接,謝謝!),但我的問題是:什麼是IncrementDecrement這裏?它們如何適合Elm的類型系統?

+1

Elm指南在[Union Types here](https://guide.elm-lang.org/types/union_types.html)上有更詳細的討論。 –

+0

我還注意到,定義的聯合類型'Msg'沒有在示例中的其他地方使用。是否必須以這種方式進行定義,以便我們可以在'update'函數中使用'case'語句? –

+1

由於其他函數在本例中沒有註釋,所以在其他地方沒有看到'Msg'(在Elm中它們不會被註解,但它可能對註釋函數非常有幫助)。假設'Model'是'Int'類型別名,類型註釋應該是:'view:model - > Html Msg'和'update:Msg - > Model - > Model' –

回答

3

IncrementDecrement是數據構造函數。你可以將它們想象成OO構造函數,它們可以有參數,更重要的是,可以區分它們。

你是對的,他們確實是一個信息;但由於它們沒有參數,它們與枚舉值沒有區別。價值是不可改變的事實與它無關。 C/C++/Java也支持枚舉。

在這種特殊情況下,您甚至可以將Msg想象爲boolean的奇特名稱。

總和類型實際上大部分類似於C中的聯合類型。區別在於,它在Elm中存儲了它的選項。 Elm從Haskell中獲得了這些概念。

+0

最近我開始學習Haskell ,而當我意識到Elm的許多語法來自何處時,我確實有動力從絆倒Elm那裏這樣做。我相信工會在Haskell中被稱爲代數數據類型?無論如何,我離題 - 很好的答案! –