首页 文章

对数据声明的类型类约束

提问于
浏览
20

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

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

2 回答

  • 23

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

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

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

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

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

  • 8

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

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

    对数据类型设置约束实际上会将其放在提及约束类型的所有构造函数上 . 与具有约束的普通函数一样,如果使用构造函数,则必须添加约束 . 我认为这是 Health 的,高于董事会 .

    它确实可以通过使用一个来创建一个编程失礼,并且's not bad practice, it'只是没有他们想要的那么可爱 .

    "bad idea to allow"可能是因为GADT真的是他们想要的 .
    如果GADT首先出现,他们就不会这样做 .

    我认为两者都不是一件坏事 . 如果需要状态操作函数,可以使用传递的永久显式参数,或者可以使用monad并使其隐式 . 如果要对数据进行约束,可以在数据声明上使用永久显式的约束,或者在GADT上使用隐式约束 . GADT和monad更复杂,但它不会使显式参数或数据类型约束错误 .

相关问题