分层数据类型

Gui*_*rel 5 haskell

我想分层定义数据类型,例如:

data Cat = BigCat | SmallCat
data Animal = Cat | Dog
Run Code Online (Sandbox Code Playgroud)

然后编写一个将Animals作为参数的函数,并使用如下模式匹配来编写它:

bigger::Animal -> Animal -> Bool
bigger SmallCat BigCat = False
bigger BigCat SmallCat = True
bigger Dog Cat = True
bigger Cat Dog = False
Run Code Online (Sandbox Code Playgroud)

编译器抱怨.它不希望Animal将函数签名中明确写入的类型Cat与模式匹配的第一行和第二行中的类型进行匹配.为什么哈斯克尔不承认大猫或小猫动物?

fuz*_*fuz 18

您将类型与其构造函数混合在一起.类型是您可以创建变量的类型.类型构造函数是用于创建此类数据的构造函数.在你的代码,data Animal = Cat | Dog声明了一个类型 Animal与两个构造 CatDog.在另一行中,您定义了一种数据类型Cat.这没有问题,因为类型和构造函数不共享相同的命名空间.

如果您希望Cat在您的类型中嵌入类型的对象Animal(如果使用了构造函数Cat),则可以向构造函数添加一个字段:

data Animal = Cat Cat | Dog
Run Code Online (Sandbox Code Playgroud)

这意味着:" Animal是具有两个构造一个类型,CatDog.Cat具有类型字段CatDog具有无".如果要使用构造函数创建对象,则Cat必须将类型对象传递Cat给它:

myCat = Cat BigCat
Run Code Online (Sandbox Code Playgroud)

如果要匹配Animal,则必须列出匹配构造函数的所有字段.比较代码的更正版本:

data Cat = BigCat | SmallCat
data Animal = Cat Cat | Dog

bigger :: Animal -> Animal -> Bool
bigger (Cat SmallCat) (Cat BigCat)   = False
bigger (Cat BigCat)   (Cat SmallCat) = True
bigger Dog            (Cat _)        = True
bigger (Cat _)         Dog           = False
Run Code Online (Sandbox Code Playgroud)

_代表不关心 -不管传递的对象,这将始终一致.

  • +1用于解释适合初学者的类型和构造函数之间的区别. (5认同)

C. *_*ann 12

这里的直接错误Animal是定义了两个与数据构造函数无关Cat的表达式:表达式Cat是类型Animal,而表达式BigCat是类型Cat.

要以简单的方式创建嵌套数据类型,您需要使Cat类型成为相关构造函数的参数:

data Cat = BigCat | SmallCat
data Animal = Cat Cat | Dog
Run Code Online (Sandbox Code Playgroud)

然后你可以做这样的事情:

bigger (Cat SmallCat) (Cat BigCat) = False
bigger (Cat BigCat) (Cat SmallCat) = True
bigger Dog (Cat _) = True
bigger (Cat _) Dog = False
Run Code Online (Sandbox Code Playgroud)

如果超出一个简单的例子,这变得非常笨拙,但是,Cat类型中的冗余是痛苦的,并且标识符的两种不同用途Cat是不必要的混淆.略微改进是避免将物种大小与物种混为一谈,而是做这样的事情:

data Size = Big | Small
data Species = Cat | Dog
data Animal = Animal Species Size
Run Code Online (Sandbox Code Playgroud)

这里的一个优点是,您可以更轻松地扩展任何类型,而无需添加尽可能多的样板废话.

然而,除了玩具示例之外,这两者都非常愚蠢,在实际使用中,很可能是一种更好的方法.如果真的类型简单枚举比猫狗,然后更加有意义deriving Ord,Enum,&C.比特殊用途的东西更好.如果意图是一种更加开放的方式来建模具有各种属性的实体,那么值得考虑更适合实际问题的其他设计.