如何在Haskell中使用自定义数据类型中的语法和访问值



我定义了一个数据类型,如:

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区分开来。

现在,对于任何特定的aMyType 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)——具有相同的ab

因此,如果你只想从abs中获得a的列表,你可以写

baz :: MyType (a,b) -> [a]
baz (MkMyType _ abs)  =  takeFirsts abs

在这里你需要实现

takeFirsts :: [(a,b)] -> [a]
takeFirsts abs  =  ...

我把它留给你来完成,作为练习。

最新更新