2016-10-04 62 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中被称为代数数据类型?无论如何,我离题 - 很好的答案! –