我的数据构造函数中不能包含String?

时间:2012-09-22 12:16:25

标签: haskell

我想将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)

它说:data / newtype声明中构造函数的错误:[Char]

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

2 个答案:

答案 0 :(得分: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总是产生类型为String的值。因此,另一种可能的定义如下:

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

答案 1 :(得分:1)

  

数据Car = Wheel |主干|字符串派生(显示)

在这里,您使用构造函数CarWheel Trunk 声明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