我正在阅读http://elm-lang.org/guide/model-the-problem,希望更好地了解榆树中的标记联盟。具体来说,我遇到了这个例子:
type Scale = Normal | Logarithmic
type Widget
= ScatterPlot (List (Int, Int))
| LogData (List String)
| TimePlot Scale (List (Time, Int))
我认为它的解释方式如下:
Scale
是一种包含2个可能值的类型:Normal
或Logarithmic
Widget
是一种包含3个可能值的类型:ScatterPlot
,LogData
或TimePlot
但是,如何解释(List (Int, Int))
中的ScatterPlot
部分?同样,如何解释Scale (List (Time, Int))
中的TimePlot
部分?
答案 0 :(得分:3)
List
是一个内置类型,带有一个参数(另一种类型),意思是“包含此类型值作为其元素的列表”。因此List (Int, Int)
是(Int, Int)
的列表。那是什么(Int, Int)
?
通常,任何(a, b)
都是一个元组,其成员类型为a
,类型为b
。元组有点像没有字段名称的记录,因此您只能按位置区分元素 - 但是与列表不同,元素可以是不同类型。因此(Int, Int)
是一个包含两个Int
s的元组,其中Int
只是一个整数。
因此,List (Int, Int)
是两个整数的元组列表。
使用TimePlot
,您实际上有两种不同的类型参数 - Scale
和List (Time, Int)
。后者现在应该有意义,因为List (Int, Int)
的解释 - 只有元组有Time
作为它的第一个类型而不是Int
。
因此TimePlot
将两种类型作为参数,它变为TimePlot Scale (List (Time, Int))
。
在Elm和相关语言中,定义了表示法(和函数应用程序),使得任何表达式a b c d
表示a
,其参数为b
,c
和{{ 1}}。如果d
是一个参数,则将其放在括号中。
正如安德烈亚斯所说,将联合'标签'视为函数 - 它们确实是,实际上它们被称为“类型构造函数”。 c d
是一个功能TimePlot
和Scale
并返回List (Time, Int)
。 Widget
是一个没有参数的函数,它返回Normal
,依此类推。
答案 1 :(得分:1)
将它们视为功能签名。因此必须像这样创建Scatterplot
ScatterPlot [(1,1), (2,2)]
当你在case
语句
case widget of
ScatterPlot l -> l -- l is from type (List (Int, Int))
LogData l -> l -- l is from type (List String)
TimePlot l -> l -- l is from type Scale (List (Time, Int))