我想将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]
那么如何创建一个数据类型,其中一个构造函数也是一个字符串?
答案 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 |主干|字符串派生(显示)
在这里,您使用构造函数Car
,Wheel
和 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