对数据声明的类型类约束

ami*_*dfv 20 haskell types typeclass

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

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

C. *_*ann 23

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

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

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

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

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


And*_*ewC 8

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

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

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

确实可以确保您不能将数据放入数据类型中,除非您可以使用它执行某些操作.它很有用.你不会通过使用一个来创建一个编程失礼,这不是坏习惯,它不像他们想要的那样可爱.

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

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