Haskell-包-如何在Haskell中使用多态?

时间:2018-10-16 20:35:18

标签: haskell polymorphism

我刚刚开始学习Haskell,但仍然没有掌握函数式编程。我需要创建一个多态数据类型,直到我编写的函数之一运行之前,我才知道其类型。该程序似乎要我从列表中构建元组列表,例如:

['Car', 'Car', 'Motorcycle', 'Motorcycle', 'Motorcycle', 'Truck']将转换为[('Car', 2), ('Motorcycle', 3), ('Truck', 1)]

在相同的元组列表(一个包)中,所有元素都属于同一类型,但是不同的包中可能包含其他类型。现在,我的数据类型声明(我不确定在FP中是否称为“声明”)

type Amount = Int
data Bag a = [(a, Amount)]

但是,当我尝试加载模块时,出现此错误:

Cannot parse data constructor in a data/newtype declaration: [(a, Amount)]

如果在声明中将data更改为type,则会收到所有功能的错误消息:

Expecting one more argument to ‘Bag’
Expected a type, but ‘Bag’ has kind ‘* -> *’

关于FP,我是否不了解某些事情?还是代码错误?更重要的是,如何以一种实际上允许我将模块加载到GHCi中的方式声明这一点?

1 个答案:

答案 0 :(得分:8)

定义data类型

这与函数式编程本身无关。如果您定义data类型(或newtype),则在Haskell中它需要一个数据构造函数(对于newtype,只能有一个 数据构造函数,并带有一个参数)。对于数据构造函数,[(a, Amount)]并不是一个好“名字”(无论如何,您都不打算将其用作数据构造函数)。

我们在这里可以编写一个数据构造函数,例如:

data Bag a = Bag [(a, Amount)]

,由于这里Bag包含(可能)一个带有 one 参数的数据构造函数,因此我们可以将其设为newtype

newtype Bag a = Bag [(a, Amount)]

但是,上面的内容可能不是必需的:您可能想用type声明 alias 类型:

type Bag a = [(a, Amount)]

在那种情况下,您没有构造新的类型,但是您可以编写Bag a,并且在“幕后”,Haskell将其替换为[(a, Amount)]

Bag定义功能

如果您现在想定义一个处理Bag的函数,则还需要在签名中指定参数a,例如:

count :: Eq a => [a] -> Bag a
count =  -- ...

现在很明显,我们在aBag中转换了a个列表。