对数据声明的类型类约束

时间:2012-10-07 15:47:39

标签: haskell types typeclass

显然,对数据声明 [src][src]添加类型类约束是个坏主意。

我个人并没有想要限制我创建的数据类型中的类型,但对于我来说,为什么语言设计师“认为允许这是一个坏主意”并不明显。那是为什么?

2 个答案:

答案 0 :(得分:23)

  

我个人并没有想要限制我创建的数据类型中的类型,但对于我来说,为什么语言设计师“认为允许这是一个坏主意”并不明显。那是为什么?

因为它具有误导性,并且从实际有用的方面完全倒退。

特别是,实际上并没有以您可能期望的方式约束数据类型中的类型做了什么做的是对数据构造函数本身放置一个类约束,这意味着你需要在构造一个值时满足该实例......但这就是全部。

因此,例如,你不能简单地定义一个带有Ord约束的二叉搜索树,然后知道任何树都有可排序的元素;查找和插入函数本身仍然需要Ord约束。你所要阻止的只是构造一个“包含”某些非有序类型值的空树。就模式匹配而言,根本没有对包含类型的约束。

另一方面,从事Haskell工作的人并不认为合理的版本(人们倾向于假设提供数据类型的上下文)根本就不是一个坏主意!实际上,对数据类型declared with GADT syntax的类约束(广义代数数据类型,在GHC中使用GADTs语言编译指示启用)确实以明显的方式工作 - 您需要约束构造该值,并且有问题的实例也存储在GADT中,因此您不需要约束来处理值,并且GADT构造函数上的模式匹配允许您使用它捕获的实例。

答案 1 :(得分:8)

在a上添加类型类约束实际上并不是一个坏主意 数据类型 - 它非常有用,并且不会破坏您的其他代码。

糟糕的是,人们通常会期望他们可以 使用数据类型来原谅他们对函数施加约束 使用数据类型,但事实并非如此。 (你可能会认为隐式约束会导致问题。)

对数据类型设置约束实际上将它放在所有构造函数上 提到约束类型。 就像带有约束的普通函数一样,如果使用构造函数, 你必须添加约束。我认为这是健康的,高于一切。

确实确保您无法将数据放入数据类型中,除非您可以这样做 有些事情。它很有用。你不会创建一个编程 通过使用一个失礼,这不是坏习惯,它不是那么可爱 他们想要。

“允许的坏主意”可能是因为GADT确实是他们想要的 如果GADT首先出现,他们就不会这样做。

我认为两者并不是一件坏事。如果你想要一个州 操纵函数,你可以使用你传递的永久显式参数, 或者你可以使用monad并使其隐含。如果你想要约束 数据可以在数据声明或隐式数据声明中使用永久显式数据 与GADT。 GADT和monad更复杂,但它没有 显式参数或数据类型约束错误。