我定义了一个数据类型,如:
data MyType a = MyType Weight [a]
权重为type Weight = Integer.
我不太明白这里发生了什么。MyType
是由一个整数组成,还是由[a]
组成,或者两者兼而有之?
在我的例子中,我得到了MyType (a,b)
,我想知道,这是(a,b)
的列表吗?如果是,我需要使用什么语法来提取a
的列表?
MyType
是由Int
和[a]
组成的类型,因此它同时具有这两种类型。要从类型中提取列表,可以使用模式匹配:
getList :: MyType a -> [a]
getList (MyType _ a) = a
或者,您可以使用记录语法声明类型:
data MyType a = MyType { getWeight :: Weight, getList :: [a] }
自动生成开箱功能,使getList (MyType 2 [3,4]) == [3,4])
正如您所说,
data MyType a = MkMyType Weight [a]
-------- -------- ------ ---
-- type data type of type of
-- constructor 1st field 2nd field
定义数据类型。请注意,我做了一个小改动,在=
的右边写了MkMyType
,以将其与左边的MyType
区分开来。
现在,对于任何特定的a
,MyType a
都是数据类型——它是一种可以出现在定义右侧的东西。
MkMyType
尽管(类型为Weight -> [a] -> MyType a
(是数据构造函数。应用于Weight
类型的值和[a]
类型的值,它会创建一个MyType a
类型的值,它实际上同时保留了两个值——Weight
类型的值以及[a]
类型的值。
如何在计算机内存中表示该值并不重要。重要的是,我们可以在上面进行模式匹配,例如
foo :: MyType a -> (Weigth, [a])
foo (MkMyType w as) = (w, as)
--------------------
-- pattern 1st 2nd
-- field field
注意,在值MkMyType w as
中,我们有Weight
类型的值w
(我们写:w :: Weight
(,还有[a]
类型的as
——与整体类型中出现的a
相同。
因此,我们也可以定义
bar :: MyType (a,b) -> (Weigth, [(b,a)])
bar (MkMyType w abs) = (w, [(b,a) | (a,b) <- abs])
这里我们有abs :: [(a,b)]
,因为参数值的类型是MyType (a,b)
——具有相同的a
和b
。
因此,如果你只想从abs
中获得a
的列表,你可以写
baz :: MyType (a,b) -> [a]
baz (MkMyType _ abs) = takeFirsts abs
在这里你需要实现
takeFirsts :: [(a,b)] -> [a]
takeFirsts abs = ...
我把它留给你来完成,作为练习。