1

我想将 String 作为构造函数的一部分:

> data Car = Wheel | Trunk | String deriving (Show)

> test::Car->Car->Car
> test Wheel Wheel = "Wheel"
> test _ _ = ""

它说:无法将 Car 与 [Char] 匹配

如果我将构造函数更改为

> data Car = Wheel | Trunk | [Char] deriving (Show)

它说:数据/新类型声明中的构造函数错误:[Char]

那么如何创建一个构造函数也是字符串的数据类型呢?

4

2 回答 2

7

Haskell 不提供您在Car数据类型中使用的未命名联合。数据类型定义中的每个元素都必须有一个构造函数。例如,您可以定义以下数据类型。

data Car = Wheel | Trunk | Constr String

在此定义中Constr表示构造函数,并且String是其参数的类型。例如,您可以Car使用 构造类型的值Constr "Wheel"。如果你String在上面的例子中省略了,它是一个Constr不带参数调用的构造函数。同样,在您的示例中,String是一个构造函数,即使存在同名的类型。

有了Car上面的定义,你可以定义test如下。

test :: Car -> Car -> Car
test Wheel Wheel = Constr "Wheel"
test _     _     = Constr ""

String通过在定义的右侧添加构造函数,字符串被提升为Car数据类型。然而,正如评论中提到的,像这样的定义似乎有点奇怪,因为test总是产生一个 type 的值String。因此,另一个可能的定义如下。

test :: Car -> Car -> String
test Wheel Wheel = "Wheel"
test _     _     = ""
于 2012-09-22T12:42:03.870 回答
1

数据汽车 = 车轮 | 后备箱 | 字符串推导(显示)

在这里,您Car使用构造函数声明WheelTrunk并且String. 您String与标准 String 类型不同,因此它们不一样。因此,您不能简单地将其与诸如"". 如果你想给它一个字符串值,让构造函数接受一个字符串,例如:

data Car = Wheel | Trunk | CarName String deriving (Show)

然后你可以像这样使用它:

test::Car->Car->Car
test Wheel Wheel = CarName "Wheel"
test _ _ = CarName ""

此函数的结果必须与构造函数匹配,例如:

let x = test Wheel Wheel 
in case x of
     Wheel -> ... -- do something if it's wheel
     Trunk -> ... -- do something if it's trunk
     CarName x -> ... -- do something if it's carname, you can use the returned x
于 2012-09-22T12:50:48.957 回答