如你所说,
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-type 值和[a]-type 值,它会创建一个MyType a 类型的值,它确实保留了两个值同时 -- 一个Weight-type 值和一个[a]-type 值,它们是在创建时给它的。
这个值如何在计算机内存中表示并不重要。重要的是我们可以在其上进行模式匹配,例如
foo :: MyType a -> (Weigth, [a])
foo (MkMyType w as) = (w, as)
--------------------
-- pattern 1st 2nd
-- field field
请注意,在值MkMyType w as 中,我们有w 类型为Weight(我们写为:w :: Weight),我们还有as 类型为[a]——具有相同的@987654341 @ 出现在整体类型中。
因此我们也可以定义
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获取as的列表,可以这样写
baz :: MyType (a,b) -> [a]
baz (MkMyType _ abs) = takeFirsts abs
这里你需要实现
takeFirsts :: [(a,b)] -> [a]
takeFirsts abs = ...
我留给你完成,作为练习。